Add different transcoding profiles for diff. device models
This commit is contained in:
parent
39ea39ca1c
commit
db24f21c69
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue