rebase added hlsStreamURL param

This commit is contained in:
jhays 2022-01-24 17:57:00 -06:00
parent 56b60dafdc
commit 0749fa0520
2 changed files with 153 additions and 121 deletions

View File

@ -169,125 +169,156 @@ extension BaseItemDto {
func createLiveTVVideoPlayerViewModel() -> AnyPublisher<[VideoPlayerViewModel], Error> { func createLiveTVVideoPlayerViewModel() -> AnyPublisher<[VideoPlayerViewModel], Error> {
LogManager.shared.log.debug("Creating liveTV video player view model for item: \(id ?? "")") LogManager.shared.log.debug("Creating liveTV video player view model for item: \(id ?? "")")
let builder = DeviceProfileBuilder() let builder = DeviceProfileBuilder()
// TODO: fix bitrate settings // TODO: fix bitrate settings
let tempOverkillBitrate = 360_000_000 let tempOverkillBitrate = 360_000_000
builder.setMaxBitrate(bitrate: tempOverkillBitrate) builder.setMaxBitrate(bitrate: tempOverkillBitrate)
let profile = builder.buildProfile() let profile = builder.buildProfile()
let playbackInfo = PlaybackInfoDto(userId: SessionManager.main.currentLogin.user.id, let playbackInfo = PlaybackInfoDto(userId: SessionManager.main.currentLogin.user.id,
maxStreamingBitrate: tempOverkillBitrate, maxStreamingBitrate: tempOverkillBitrate,
startTimeTicks: self.userData?.playbackPositionTicks ?? 0, startTimeTicks: self.userData?.playbackPositionTicks ?? 0,
deviceProfile: profile, deviceProfile: profile,
autoOpenLiveStream: true) autoOpenLiveStream: true)
return MediaInfoAPI.getPostedPlaybackInfo(itemId: self.id!, return MediaInfoAPI.getPostedPlaybackInfo(itemId: self.id!,
userId: SessionManager.main.currentLogin.user.id, userId: SessionManager.main.currentLogin.user.id,
maxStreamingBitrate: tempOverkillBitrate, maxStreamingBitrate: tempOverkillBitrate,
startTimeTicks: self.userData?.playbackPositionTicks ?? 0, startTimeTicks: self.userData?.playbackPositionTicks ?? 0,
autoOpenLiveStream: true, autoOpenLiveStream: true,
playbackInfoDto: playbackInfo) playbackInfoDto: playbackInfo)
.map { response -> [VideoPlayerViewModel] in .map { response -> [VideoPlayerViewModel] in
let mediaSources = response.mediaSources! let mediaSources = response.mediaSources!
var viewModels: [VideoPlayerViewModel] = [] var viewModels: [VideoPlayerViewModel] = []
for currentMediaSource in mediaSources { for currentMediaSource in mediaSources {
let audioStreams = currentMediaSource.mediaStreams?.filter { $0.type == .audio } ?? [] let videoStream = currentMediaSource.mediaStreams?.filter { $0.type == .video }.first
let subtitleStreams = currentMediaSource.mediaStreams?.filter { $0.type == .subtitle } ?? [] let audioStreams = currentMediaSource.mediaStreams?.filter { $0.type == .audio } ?? []
let subtitleStreams = currentMediaSource.mediaStreams?.filter { $0.type == .subtitle } ?? []
let defaultAudioStream = audioStreams.first(where: { $0.index! == currentMediaSource.defaultAudioStreamIndex! })
let defaultAudioStream = audioStreams.first(where: { $0.index! == currentMediaSource.defaultAudioStreamIndex! })
let defaultSubtitleStream = subtitleStreams
.first(where: { $0.index! == currentMediaSource.defaultSubtitleStreamIndex ?? -1 }) let defaultSubtitleStream = subtitleStreams
.first(where: { $0.index! == currentMediaSource.defaultSubtitleStreamIndex ?? -1 })
var directStreamURL: URL
let transcodedStreamURL: URLComponents? // MARK: Build Streams
let mediaSourceID: String
let streamType: ServerStreamType let directStreamURL: URL
let transcodedStreamURL: URLComponents?
if let transcodeURL = currentMediaSource.transcodingUrl { var hlsStreamURL: URL
streamType = .transcode let mediaSourceID: String
transcodedStreamURL = URLComponents(string: SessionManager.main.currentLogin.server.currentURI let streamType: ServerStreamType
.appending(transcodeURL))!
} else { if mediaSources.count > 1 {
streamType = .direct mediaSourceID = currentMediaSource.id!
transcodedStreamURL = nil } else {
} mediaSourceID = self.id!
}
if mediaSources.count > 1 {
mediaSourceID = currentMediaSource.id! let directStreamBuilder = VideosAPI.getVideoStreamWithRequestBuilder(itemId: self.id!,
} else { _static: true,
mediaSourceID = self.id! tag: self.etag,
} playSessionId: response.playSessionId,
minSegments: 6,
let requestBuilder = VideosAPI.getVideoStreamWithRequestBuilder(itemId: self.id!, mediaSourceId: mediaSourceID)
_static: true, directStreamURL = URL(string: directStreamBuilder.URLString)!
tag: self.etag,
minSegments: 6, if let transcodeURL = currentMediaSource.transcodingUrl {
mediaSourceId: mediaSourceID) streamType = .transcode
directStreamURL = URL(string: requestBuilder.URLString)! transcodedStreamURL = URLComponents(string: SessionManager.main.currentLogin.server.currentURI
.appending(transcodeURL))!
// MARK: VidoPlayerViewModel Creation } else {
streamType = .direct
var subtitle: String? transcodedStreamURL = nil
}
// MARK: Attach media content to self
let hlsStreamBuilder = DynamicHlsAPI.getMasterHlsVideoPlaylistWithRequestBuilder(itemId: id ?? "",
var modifiedSelfItem = self mediaSourceId: id ?? "",
modifiedSelfItem.mediaStreams = currentMediaSource.mediaStreams _static: true,
tag: currentMediaSource.eTag,
// TODO: other forms of media subtitle deviceProfileId: nil,
if self.itemType == .episode { playSessionId: response.playSessionId,
if let seriesName = self.seriesName, let episodeLocator = self.getEpisodeLocator() { segmentContainer: "ts",
subtitle = "\(seriesName) - \(episodeLocator)" segmentLength: nil,
} minSegments: 2,
} deviceId: UIDevice.vendorUUIDString,
audioCodec: audioStreams
let subtitlesEnabled = defaultSubtitleStream != nil .compactMap(\.codec)
.joined(separator: ","),
let shouldShowAutoPlay = Defaults[.shouldShowAutoPlay] && itemType == .episode breakOnNonKeyFrames: true,
let autoplayEnabled = Defaults[.autoplayEnabled] && shouldShowAutoPlay requireAvc: true,
transcodingMaxAudioChannels: 6,
let overlayType = Defaults[.overlayType] videoCodec: videoStream?.codec,
videoStreamIndex: videoStream?.index,
let shouldShowPlayPreviousItem = Defaults[.shouldShowPlayPreviousItem] && itemType == .episode enableAdaptiveBitrateStreaming: true)
let shouldShowPlayNextItem = Defaults[.shouldShowPlayNextItem] && itemType == .episode
var hlsStreamComponents = URLComponents(string: hlsStreamBuilder.URLString)!
var fileName: String? hlsStreamComponents.addQueryItem(name: "api_key", value: SessionManager.main.currentLogin.user.accessToken)
if let lastInPath = currentMediaSource.path?.split(separator: "/").last {
fileName = String(lastInPath) hlsStreamURL = hlsStreamComponents.url!
}
// MARK: VidoPlayerViewModel Creation
let videoPlayerViewModel = VideoPlayerViewModel(item: modifiedSelfItem,
title: modifiedSelfItem.name ?? "", var subtitle: String?
subtitle: subtitle,
directStreamURL: directStreamURL, // MARK: Attach media content to self
transcodedStreamURL: transcodedStreamURL?.url,
streamType: streamType, var modifiedSelfItem = self
response: response, modifiedSelfItem.mediaStreams = currentMediaSource.mediaStreams
audioStreams: audioStreams,
subtitleStreams: subtitleStreams, // TODO: other forms of media subtitle
chapters: modifiedSelfItem.chapters ?? [], if self.itemType == .episode {
selectedAudioStreamIndex: defaultAudioStream?.index ?? -1, if let seriesName = self.seriesName, let episodeLocator = self.getEpisodeLocator() {
selectedSubtitleStreamIndex: defaultSubtitleStream?.index ?? -1, subtitle = "\(seriesName) - \(episodeLocator)"
subtitlesEnabled: subtitlesEnabled, }
autoplayEnabled: autoplayEnabled, }
overlayType: overlayType,
shouldShowPlayPreviousItem: shouldShowPlayPreviousItem, let subtitlesEnabled = defaultSubtitleStream != nil
shouldShowPlayNextItem: shouldShowPlayNextItem,
shouldShowAutoPlay: shouldShowAutoPlay, let shouldShowAutoPlay = Defaults[.shouldShowAutoPlay] && itemType == .episode
container: currentMediaSource.container ?? "", let autoplayEnabled = Defaults[.autoplayEnabled] && shouldShowAutoPlay
filename: fileName,
versionName: currentMediaSource.name) let overlayType = Defaults[.overlayType]
viewModels.append(videoPlayerViewModel) let shouldShowPlayPreviousItem = Defaults[.shouldShowPlayPreviousItem] && itemType == .episode
} let shouldShowPlayNextItem = Defaults[.shouldShowPlayNextItem] && itemType == .episode
return viewModels var fileName: String?
} if let lastInPath = currentMediaSource.path?.split(separator: "/").last {
.eraseToAnyPublisher() fileName = String(lastInPath)
}
let videoPlayerViewModel = VideoPlayerViewModel(item: modifiedSelfItem,
title: modifiedSelfItem.name ?? "",
subtitle: subtitle,
directStreamURL: directStreamURL,
transcodedStreamURL: transcodedStreamURL?.url,
hlsStreamURL: hlsStreamURL,
streamType: streamType,
response: response,
audioStreams: audioStreams,
subtitleStreams: subtitleStreams,
chapters: modifiedSelfItem.chapters ?? [],
selectedAudioStreamIndex: defaultAudioStream?.index ?? -1,
selectedSubtitleStreamIndex: defaultSubtitleStream?.index ?? -1,
subtitlesEnabled: subtitlesEnabled,
autoplayEnabled: autoplayEnabled,
overlayType: overlayType,
shouldShowPlayPreviousItem: shouldShowPlayPreviousItem,
shouldShowPlayNextItem: shouldShowPlayNextItem,
shouldShowAutoPlay: shouldShowAutoPlay,
container: currentMediaSource.container ?? "",
filename: fileName,
versionName: currentMediaSource.name)
viewModels.append(videoPlayerViewModel)
}
return viewModels
}
.eraseToAnyPublisher()
} }
} }

View File

@ -142,7 +142,8 @@ struct tvOSLiveTVOverlay_Previews: PreviewProvider {
title: "Glorious Purpose", title: "Glorious Purpose",
subtitle: "Loki - S1E1", subtitle: "Loki - S1E1",
directStreamURL: URL(string: "www.apple.com")!, directStreamURL: URL(string: "www.apple.com")!,
transcodedStreamURL: nil, transcodedStreamURL: nil,
hlsStreamURL: URL(string: "www.apple.com")!,
streamType: .direct, streamType: .direct,
response: PlaybackInfoResponse(), response: PlaybackInfoResponse(),
audioStreams: [MediaStream(displayTitle: "English", index: -1)], audioStreams: [MediaStream(displayTitle: "English", index: -1)],