Add different transcoding profiles for diff. device models

This commit is contained in:
Aiden Vigue 2021-05-23 00:10:12 -04:00
parent 39ea39ca1c
commit db24f21c69
1 changed files with 139 additions and 3 deletions

View File

@ -10,6 +10,8 @@ import SwiftyJSON
import SwiftyRequest
import AVKit
import MobileVLCKit
import Foundation
import NotificationCenter
struct Subtitle {
var name: String;
@ -36,6 +38,94 @@ extension String {
}
}
extension UIDevice
{
//Original Author: HAS
// https://stackoverflow.com/questions/26028918/how-to-determine-the-current-iphone-device-model
// Modified by Sam Trent
/**********************************************
* getCPUName():
* Returns a hardcoded value of the current
* devices CPU name.
***********************************************/
public func getCPUName() -> Float
{
let processorNames = Array(CPUinfo().keys)
return processorNames[0]
}
/**********************************************
* getCPUSpeed():
* Returns a hardcoded value of the current
* devices CPU speed as specified by Apple.
***********************************************/
public func getCPUSpeed() -> String
{
let processorSpeed = Array(CPUinfo().values)
return processorSpeed[0]
}
/**********************************************
* CPUinfo:
* Returns a dictionary of the name of the
* current devices processor and speed.
***********************************************/
private func CPUinfo() -> Dictionary<Float, String> {
#if targetEnvironment(simulator)
let identifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"]!
#else
var systemInfo = utsname()
uname(&systemInfo)
let machineMirror = Mirror(reflecting: systemInfo.machine)
let identifier = machineMirror.children.reduce("") { identifier, element in
guard let value = element.value as? Int8 , value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}
#endif
switch identifier {
case "iPod5,1": return [5:"800 MHz"] // underclocked
case "iPod7,1": return [8:"1.4 GHz"]
case "iPhone3,1", "iPhone3,2", "iPhone3,3": return [4:"800 MHz"] // underclocked
case "iPhone4,1": return [5:"800 MHz"] // underclocked
case "iPhone5,1", "iPhone5,2": return [6:"1.3 GHz"]
case "iPhone5,3", "iPhone5,4": return [6:"1.3 GHz"]
case "iPhone6,1", "iPhone6,2": return [7:"1.3 GHz"]
case "iPhone7,2": return [8:"1.4 GHz"]
case "iPhone7,1": return [8:"1.4 GHz"]
case "iPhone8,1": return [9:"1.85 GHz"]
case "iPhone8,2": return [9:"1.85 GHz"]
case "iPhone9,1", "iPhone9,3": return [10:"2.34 GHz"]
case "iPhone9,2", "iPhone9,4": return [10:"2.34 GHz"]
case "iPhone8,4": return [9:"1.85 GHz"]
case "iPhone10,1", "iPhone10,4": return [11:"2.39 GHz"]
case "iPhone10,2", "iPhone10,5": return [11:"2.39 GHz"]
case "iPhone10,3", "iPhone10,6": return [11:"2.39 GHz"]
case "iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4":return [5:"1.0 GHz"]
case "iPad3,1", "iPad3,2", "iPad3,3": return [5.5:"1.0 GHz"]
case "iPad3,4", "iPad3,5", "iPad3,6": return [6.5:"1.4 GHz"]
case "iPad4,1", "iPad4,2", "iPad4,3": return [7:"1.4 GHz"]
case "iPad5,3", "iPad5,4": return [8.5:"1.5 GHz"]
case "iPad6,11", "iPad6,12": return [9:"1.85 GHz"]
case "iPad2,5", "iPad2,6", "iPad2,7": return [5:"1.0 GHz"]
case "iPad4,4", "iPad4,5", "iPad4,6": return [7:"1.3 GHz"]
case "iPad4,7", "iPad4,8", "iPad4,9": return [7:"1.3 GHz"]
case "iPad5,1", "iPad5,2": return [8:"1.5 GHz"]
case "iPad6,3", "iPad6,4": return [9.5:"2.16 GHz"] // underclocked
case "iPad6,7", "iPad6,8": return [9.5:"2.24 GHz"]
case "iPad7,1", "iPad7,2": return [10.5:"2.34 GHz"]
case "iPad7,3", "iPad7,4": return [10.5:"2.34 GHz"]
case "AppleTV5,3": return [8:"1.4 GHz"]
case "AppleTV6,2": return [10.5:"2.34 GHz"]
case "AudioAccessory1,1": return [8:"1.4 GHz"] // clock speed is a guess
default: return [99:"N/A"]
}
}
}
struct PlayerDemo: View {
@EnvironmentObject var globalData: GlobalData
var item: DetailItem;
@ -204,12 +294,57 @@ struct PlayerDemo: View {
}
func startStream() {
let cpuModel = UIDevice.current.getCPUName();
var directStreamVideoProfiles: [String] = ["h264"];
var transcodedStreamVideoProfiles: [String] = ["h264"];
var directStreamAudioProfiles: [String] = ["aac","mp3","vorbis"];
var transcodedStreamAudioProfiles: [String] = ["aac","mp3","vorbis"];
//HEVC support started 9 (9) - also adds Dolby Digital & FLAC
if(cpuModel >= 9) {
directStreamVideoProfiles.append("hevc");
transcodedStreamVideoProfiles.append("hevc");
directStreamAudioProfiles.append("ac3");
directStreamAudioProfiles.append("eac3");
directStreamAudioProfiles.append("flac");
transcodedStreamAudioProfiles.append("ac3");
transcodedStreamAudioProfiles.append("eac3");
transcodedStreamAudioProfiles.append("flac");
}
//Dolby Vision support started 11 Bionic (11)
if(cpuModel >= 11) {
directStreamVideoProfiles.append("dvav");
transcodedStreamVideoProfiles.append("dvav");
directStreamVideoProfiles.append("dva1");
transcodedStreamVideoProfiles.append("dva1");
directStreamVideoProfiles.append("dvh1");
transcodedStreamVideoProfiles.append("dvh1");
directStreamVideoProfiles.append("dvhe");
transcodedStreamVideoProfiles.append("dvhe");
}
//Dolby Atmos support started 12 Bionic (12)
if(cpuModel >= 12) {
directStreamAudioProfiles.append("dts");
directStreamAudioProfiles.append("truehd");
directStreamAudioProfiles.append("dca");
transcodedStreamAudioProfiles.append("dts");
transcodedStreamAudioProfiles.append("truehd");
transcodedStreamAudioProfiles.append("dca");
}
_streamLoading.wrappedValue = true;
let request = RestRequest(method: .post, url: (globalData.server?.baseURI ?? "") + "/Items/\(item.Id)/PlaybackInfo?UserId=\(globalData.user?.user_id ?? "")&StartTimeTicks=\(Int(item.Progress))&IsPlayback=true&AutoOpenLiveStream=true&MaxStreamingBitrate=70000000")
request.headerParameters["X-Emby-Authorization"] = globalData.authHeader
request.contentType = "application/json"
request.acceptType = "application/json"
request.messageBody = "{\"DeviceProfile\":{\"MaxStreamingBitrate\":70000000,\"MaxStaticBitrate\":140000000,\"MusicStreamingTranscodingBitrate\":384000,\"DirectPlayProfiles\":[{\"Container\":\"webm\",\"Type\":\"Video\",\"VideoCodec\":\"vp8\",\"AudioCodec\":\"vorbis\"},{\"Container\":\"mp4,m4v,mkv,mov\",\"Type\":\"Video\",\"VideoCodec\":\"hevc,h264,vp8,dvhe,dva1,dvh1\",\"AudioCodec\":\"aac,mp3,ac3,eac3,flac,alac,vorbis,dts,dca,truehd\"},{\"Container\":\"mp3\",\"Type\":\"Audio\"},{\"Container\":\"aac\",\"Type\":\"Audio\"},{\"Container\":\"m4a\",\"AudioCodec\":\"aac\",\"Type\":\"Audio\"},{\"Container\":\"m4b\",\"AudioCodec\":\"aac\",\"Type\":\"Audio\"},{\"Container\":\"flac\",\"Type\":\"Audio\"},{\"Container\":\"alac\",\"Type\":\"Audio\"},{\"Container\":\"m4a\",\"AudioCodec\":\"alac\",\"Type\":\"Audio\"},{\"Container\":\"m4b\",\"AudioCodec\":\"alac\",\"Type\":\"Audio\"},{\"Container\":\"webma\",\"Type\":\"Audio\"},{\"Container\":\"webm\",\"AudioCodec\":\"webma\",\"Type\":\"Audio\"},{\"Container\":\"wav\",\"Type\":\"Audio\"}],\"TranscodingProfiles\":[{\"Container\":\"aac\",\"Type\":\"Audio\",\"AudioCodec\":\"aac\",\"Context\":\"Streaming\",\"Protocol\":\"hls\",\"MaxAudioChannels\":\"6\",\"MinSegments\":\"2\",\"BreakOnNonKeyFrames\":true},{\"Container\":\"aac\",\"Type\":\"Audio\",\"AudioCodec\":\"aac\",\"Context\":\"Streaming\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"mp3\",\"Type\":\"Audio\",\"AudioCodec\":\"mp3\",\"Context\":\"Streaming\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"wav\",\"Type\":\"Audio\",\"AudioCodec\":\"wav\",\"Context\":\"Streaming\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"mp3\",\"Type\":\"Audio\",\"AudioCodec\":\"mp3\",\"Context\":\"Static\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"aac\",\"Type\":\"Audio\",\"AudioCodec\":\"aac\",\"Context\":\"Static\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"wav\",\"Type\":\"Audio\",\"AudioCodec\":\"wav\",\"Context\":\"Static\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"ts\",\"Type\":\"Video\",\"AudioCodec\":\"aac,mp3,ac3,eac3,dts,dca,truehd\",\"VideoCodec\":\"h264,hevc\",\"Context\":\"Streaming\",\"Protocol\":\"hls\",\"MaxAudioChannels\":\"6\",\"MinSegments\":\"2\",\"BreakOnNonKeyFrames\":true},{\"Container\":\"webm\",\"Type\":\"Video\",\"AudioCodec\":\"vorbis\",\"VideoCodec\":\"vpx\",\"Context\":\"Streaming\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"mp4\",\"Type\":\"Video\",\"AudioCodec\":\"aac,mp3,ac3,eac3,flac,alac,vorbis,dts,dca,truehd\",\"VideoCodec\":\"h264,hevc\",\"Context\":\"Static\",\"Protocol\":\"http\"}],\"ContainerProfiles\":[],\"CodecProfiles\":[{\"Type\":\"Video\",\"Codec\":\"h264\",\"Conditions\":[{\"Condition\":\"NotEquals\",\"Property\":\"IsAnamorphic\",\"Value\":\"true\",\"IsRequired\":false},{\"Condition\":\"EqualsAny\",\"Property\":\"VideoProfile\",\"Value\":\"high|main|baseline|constrained baseline\",\"IsRequired\":false},{\"Condition\":\"LessThanEqual\",\"Property\":\"VideoLevel\",\"Value\":\"80\",\"IsRequired\":false},{\"Condition\":\"NotEquals\",\"Property\":\"IsInterlaced\",\"Value\":\"true\",\"IsRequired\":false}]},{\"Type\":\"Video\",\"Codec\":\"hevc\",\"Conditions\":[{\"Condition\":\"NotEquals\",\"Property\":\"IsAnamorphic\",\"Value\":\"true\",\"IsRequired\":false},{\"Condition\":\"EqualsAny\",\"Property\":\"VideoProfile\",\"Value\":\"main|main 10\",\"IsRequired\":false},{\"Condition\":\"LessThanEqual\",\"Property\":\"VideoLevel\",\"Value\":\"160\",\"IsRequired\":false},{\"Condition\":\"NotEquals\",\"Property\":\"IsInterlaced\",\"Value\":\"true\",\"IsRequired\":false}]}],\"SubtitleProfiles\":[{\"Format\":\"vtt\",\"Method\":\"External\"},{\"Format\":\"ass\",\"Method\":\"External\"},{\"Format\":\"ssa\",\"Method\":\"External\"},{\"Format\":\"pgssub\",\"Method\":\"Embed\"},{\"Format\":\"pgs\",\"Method\":\"Embed\"},{\"Format\":\"sub\",\"Method\":\"Embed\"}],\"ResponseProfiles\":[{\"Type\":\"Video\",\"Container\":\"m4v\",\"MimeType\":\"video/mp4\"}]}}".data(using: .ascii);
request.messageBody = "{\"DeviceProfile\":{\"MaxStreamingBitrate\":70000000,\"MaxStaticBitrate\":140000000,\"MusicStreamingTranscodingBitrate\":384000,\"DirectPlayProfiles\":[{\"Container\":\"mp4,m4v,mkv,mov\",\"Type\":\"Video\",\"VideoCodec\":\"\(directStreamVideoProfiles.joined(separator: ","))\",\"AudioCodec\":\"\(directStreamAudioProfiles.joined(separator: ","))\"},{\"Container\":\"mp3\",\"Type\":\"Audio\"},{\"Container\":\"aac\",\"Type\":\"Audio\"},{\"Container\":\"m4a\",\"AudioCodec\":\"aac\",\"Type\":\"Audio\"},{\"Container\":\"m4b\",\"AudioCodec\":\"aac\",\"Type\":\"Audio\"},{\"Container\":\"flac\",\"Type\":\"Audio\"},{\"Container\":\"alac\",\"Type\":\"Audio\"},{\"Container\":\"m4a\",\"AudioCodec\":\"alac\",\"Type\":\"Audio\"},{\"Container\":\"m4b\",\"AudioCodec\":\"alac\",\"Type\":\"Audio\"},{\"Container\":\"webma\",\"Type\":\"Audio\"},{\"Container\":\"webm\",\"AudioCodec\":\"webma\",\"Type\":\"Audio\"},{\"Container\":\"wav\",\"Type\":\"Audio\"}],\"TranscodingProfiles\":[{\"Container\":\"aac\",\"Type\":\"Audio\",\"AudioCodec\":\"aac\",\"Context\":\"Streaming\",\"Protocol\":\"hls\",\"MaxAudioChannels\":\"6\",\"MinSegments\":\"2\",\"BreakOnNonKeyFrames\":true},{\"Container\":\"aac\",\"Type\":\"Audio\",\"AudioCodec\":\"aac\",\"Context\":\"Streaming\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"mp3\",\"Type\":\"Audio\",\"AudioCodec\":\"mp3\",\"Context\":\"Streaming\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"wav\",\"Type\":\"Audio\",\"AudioCodec\":\"wav\",\"Context\":\"Streaming\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"mp3\",\"Type\":\"Audio\",\"AudioCodec\":\"mp3\",\"Context\":\"Static\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"aac\",\"Type\":\"Audio\",\"AudioCodec\":\"aac\",\"Context\":\"Static\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"wav\",\"Type\":\"Audio\",\"AudioCodec\":\"wav\",\"Context\":\"Static\",\"Protocol\":\"http\",\"MaxAudioChannels\":\"6\"},{\"Container\":\"ts\",\"Type\":\"Video\",\"AudioCodec\":\"\(transcodedStreamAudioProfiles.joined(separator: ","))\",\"VideoCodec\":\"\(transcodedStreamVideoProfiles.joined(separator: ","))\",\"Context\":\"Streaming\",\"Protocol\":\"hls\",\"MaxAudioChannels\":\"6\",\"MinSegments\":\"2\",\"BreakOnNonKeyFrames\":true},{\"Container\":\"mp4\",\"Type\":\"Video\",\"AudioCodec\":\"\(transcodedStreamAudioProfiles.joined(separator: ","))\",\"VideoCodec\":\"\(transcodedStreamVideoProfiles.joined(separator: ","))\",\"Context\":\"Static\",\"Protocol\":\"http\"}],\"ContainerProfiles\":[],\"CodecProfiles\":[{\"Type\":\"Video\",\"Codec\":\"h264\",\"Conditions\":[{\"Condition\":\"NotEquals\",\"Property\":\"IsAnamorphic\",\"Value\":\"true\",\"IsRequired\":false},{\"Condition\":\"EqualsAny\",\"Property\":\"VideoProfile\",\"Value\":\"high|main|baseline|constrained baseline\",\"IsRequired\":false},{\"Condition\":\"LessThanEqual\",\"Property\":\"VideoLevel\",\"Value\":\"80\",\"IsRequired\":false},{\"Condition\":\"NotEquals\",\"Property\":\"IsInterlaced\",\"Value\":\"true\",\"IsRequired\":false}]},{\"Type\":\"Video\",\"Codec\":\"hevc\",\"Conditions\":[{\"Condition\":\"NotEquals\",\"Property\":\"IsAnamorphic\",\"Value\":\"true\",\"IsRequired\":false},{\"Condition\":\"EqualsAny\",\"Property\":\"VideoProfile\",\"Value\":\"main|main 10\",\"IsRequired\":false},{\"Condition\":\"LessThanEqual\",\"Property\":\"VideoLevel\",\"Value\":\"160\",\"IsRequired\":false},{\"Condition\":\"NotEquals\",\"Property\":\"IsInterlaced\",\"Value\":\"true\",\"IsRequired\":false}]}],\"SubtitleProfiles\":[{\"Format\":\"vtt\",\"Method\":\"External\"},{\"Format\":\"ass\",\"Method\":\"External\"},{\"Format\":\"ssa\",\"Method\":\"External\"},{\"Format\":\"pgssub\",\"Method\":\"Embed\"},{\"Format\":\"pgs\",\"Method\":\"Embed\"},{\"Format\":\"sub\",\"Method\":\"Embed\"}],\"ResponseProfiles\":[{\"Type\":\"Video\",\"Container\":\"m4v\",\"MimeType\":\"video/mp4\"}]}}".data(using: .ascii);
request.responseData() { (result: Result<RestResponse<Data>, RestError>) in
switch result {
@ -299,7 +434,7 @@ struct PlayerDemo: View {
VLCPlayer(url: $pbitem, player: $vlcplayer, startTime: Int(item.Progress)).onDisappear(perform: {
_isPlaying.wrappedValue = false;
vlcplayer.stop()
})
}).background(Color(UIColor.green).opacity(0.4))
VStack() {
HStack() {
HStack() {
@ -383,10 +518,11 @@ struct PlayerDemo: View {
}
.padding(EdgeInsets(top: 0, leading: UIDevice.current.hasNotch ? -30 : 0, bottom: 0, trailing: UIDevice.current.hasNotch ? -30 : 0))
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color(UIColor.black).opacity(0.4))
.background(Color(UIColor.red).opacity(0.4))
.isHidden(inactivity)
}.padding(EdgeInsets(top: 0, leading: UIDevice.current.hasNotch ? 34 : 0, bottom: 0, trailing: UIDevice.current.hasNotch ? 34 : 0))
}.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
.background(Color(UIColor.blue).opacity(0.4))
.onAppear(perform: startStream)
.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)