allow force direct play as a temporary measure

This commit is contained in:
Ethan Pippin 2022-01-15 13:01:42 -07:00
parent 601113f102
commit 13f457f52a
9 changed files with 71 additions and 25 deletions

View File

@ -48,24 +48,28 @@ extension BaseItemDto {
let defaultSubtitleStream = subtitleStreams let defaultSubtitleStream = subtitleStreams
.first(where: { $0.index! == currentMediaSource.defaultSubtitleStreamIndex ?? -1 }) .first(where: { $0.index! == currentMediaSource.defaultSubtitleStreamIndex ?? -1 })
var streamURL: URLComponents var directStreamURL: URLComponents
let transcodedStreamURL: URLComponents?
let streamType: ServerStreamType let streamType: ServerStreamType
if let transcodeURL = currentMediaSource.transcodingUrl { if let transcodeURL = currentMediaSource.transcodingUrl {
streamType = .transcode streamType = .transcode
streamURL = URLComponents(string: SessionManager.main.currentLogin.server.currentURI.appending(transcodeURL))! transcodedStreamURL = URLComponents(string: SessionManager.main.currentLogin.server.currentURI
.appending(transcodeURL))!
} else { } else {
streamType = .direct streamType = .direct
streamURL = URLComponents(string: SessionManager.main.currentLogin.server.currentURI)! transcodedStreamURL = nil
streamURL.path = "/Videos/\(self.id!)/stream" }
streamURL.addQueryItem(name: "Static", value: "true")
streamURL.addQueryItem(name: "MediaSourceId", value: self.id!)
streamURL.addQueryItem(name: "Tag", value: self.etag)
streamURL.addQueryItem(name: "MinSegments", value: "6")
if mediaSources.count > 1 { directStreamURL = URLComponents(string: SessionManager.main.currentLogin.server.currentURI)!
streamURL.addQueryItem(name: "MediaSourceId", value: currentMediaSource.id) directStreamURL.path = "/Videos/\(self.id!)/stream"
} directStreamURL.addQueryItem(name: "Static", value: "true")
directStreamURL.addQueryItem(name: "MediaSourceId", value: self.id!)
directStreamURL.addQueryItem(name: "Tag", value: self.etag)
directStreamURL.addQueryItem(name: "MinSegments", value: "6")
if mediaSources.count > 1 {
directStreamURL.addQueryItem(name: "MediaSourceId", value: currentMediaSource.id)
} }
// MARK: VidoPlayerViewModel Creation // MARK: VidoPlayerViewModel Creation
@ -102,7 +106,8 @@ extension BaseItemDto {
let videoPlayerViewModel = VideoPlayerViewModel(item: modifiedSelfItem, let videoPlayerViewModel = VideoPlayerViewModel(item: modifiedSelfItem,
title: modifiedSelfItem.name ?? "", title: modifiedSelfItem.name ?? "",
subtitle: subtitle, subtitle: subtitle,
streamURL: streamURL.url!, directStreamURL: directStreamURL.url!,
transcodedStreamURL: transcodedStreamURL?.url,
streamType: streamType, streamType: streamType,
response: response, response: response,
audioStreams: audioStreams, audioStreams: audioStreams,

View File

@ -70,6 +70,7 @@ extension Defaults.Keys {
enum Experimental { enum Experimental {
static let syncSubtitleStateWithAdjacent = Key<Bool>("experimental.syncSubtitleState", default: false, static let syncSubtitleStateWithAdjacent = Key<Bool>("experimental.syncSubtitleState", default: false,
suite: SwiftfinStore.Defaults.generalSuite) suite: SwiftfinStore.Defaults.generalSuite)
static let forceDirectPlay = Key<Bool>("forceDirectPlay", default: false, suite: SwiftfinStore.Defaults.generalSuite)
static let liveTVAlphaEnabled = Key<Bool>("liveTVAlphaEnabled", default: false, suite: SwiftfinStore.Defaults.generalSuite) static let liveTVAlphaEnabled = Key<Bool>("liveTVAlphaEnabled", default: false, suite: SwiftfinStore.Defaults.generalSuite)
} }

View File

@ -106,7 +106,8 @@ final class VideoPlayerViewModel: ViewModel {
private(set) var item: BaseItemDto private(set) var item: BaseItemDto
let title: String let title: String
let subtitle: String? let subtitle: String?
let streamURL: URL let directStreamURL: URL
let transcodedStreamURL: URL?
let audioStreams: [MediaStream] let audioStreams: [MediaStream]
let subtitleStreams: [MediaStream] let subtitleStreams: [MediaStream]
let overlayType: OverlayType let overlayType: OverlayType
@ -167,7 +168,8 @@ final class VideoPlayerViewModel: ViewModel {
init(item: BaseItemDto, init(item: BaseItemDto,
title: String, title: String,
subtitle: String?, subtitle: String?,
streamURL: URL, directStreamURL: URL,
transcodedStreamURL: URL?,
streamType: ServerStreamType, streamType: ServerStreamType,
response: PlaybackInfoResponse, response: PlaybackInfoResponse,
audioStreams: [MediaStream], audioStreams: [MediaStream],
@ -187,7 +189,8 @@ final class VideoPlayerViewModel: ViewModel {
self.item = item self.item = item
self.title = title self.title = title
self.subtitle = subtitle self.subtitle = subtitle
self.streamURL = streamURL self.directStreamURL = directStreamURL
self.transcodedStreamURL = transcodedStreamURL
self.streamType = streamType self.streamType = streamType
self.response = response self.response = response
self.audioStreams = audioStreams self.audioStreams = audioStreams
@ -561,7 +564,7 @@ extension VideoPlayerViewModel {
func createEmbeddedSubtitleStream(with subtitleStream: MediaStream) -> URL { func createEmbeddedSubtitleStream(with subtitleStream: MediaStream) -> URL {
guard let baseURL = URLComponents(url: streamURL, resolvingAgainstBaseURL: false) else { fatalError() } guard let baseURL = URLComponents(url: directStreamURL, resolvingAgainstBaseURL: false) else { fatalError() }
guard let queryItems = baseURL.queryItems else { fatalError() } guard let queryItems = baseURL.queryItems else { fatalError() }
var newURL = baseURL var newURL = baseURL
@ -593,7 +596,7 @@ extension VideoPlayerViewModel: Hashable {
func hash(into hasher: inout Hasher) { func hash(into hasher: inout Hasher) {
hasher.combine(item) hasher.combine(item)
hasher.combine(streamURL) hasher.combine(directStreamURL)
hasher.combine(filename) hasher.combine(filename)
hasher.combine(versionName) hasher.combine(versionName)
} }

View File

@ -11,6 +11,8 @@ import SwiftUI
struct ExperimentalSettingsView: View { struct ExperimentalSettingsView: View {
@Default(.Experimental.forceDirectPlay)
var forceDirectPlay
@Default(.Experimental.syncSubtitleStateWithAdjacent) @Default(.Experimental.syncSubtitleStateWithAdjacent)
var syncSubtitleStateWithAdjacent var syncSubtitleStateWithAdjacent
@Default(.Experimental.liveTVAlphaEnabled) @Default(.Experimental.liveTVAlphaEnabled)
@ -20,6 +22,8 @@ struct ExperimentalSettingsView: View {
Form { Form {
Section { Section {
Toggle("Force Direct Play", isOn: $forceDirectPlay)
Toggle("Sync Subtitles with Adjacent Episodes", isOn: $syncSubtitleStateWithAdjacent) Toggle("Sync Subtitles with Adjacent Episodes", isOn: $syncSubtitleStateWithAdjacent)
Toggle("Live TV (Alpha)", isOn: $liveTVAlphaEnabled) Toggle("Live TV (Alpha)", isOn: $liveTVAlphaEnabled)

View File

@ -425,7 +425,16 @@ extension VLCPlayerViewController {
// TODO: Custom buffer/cache amounts // TODO: Custom buffer/cache amounts
let media = VLCMedia(url: newViewModel.streamURL) let media: VLCMedia
if let transcodedURL = newViewModel.transcodedStreamURL,
!Defaults[.Experimental.forceDirectPlay]
{
media = VLCMedia(url: transcodedURL)
} else {
media = VLCMedia(url: newViewModel.directStreamURL)
}
media.addOption("--prefetch-buffer-size=1048576") media.addOption("--prefetch-buffer-size=1048576")
media.addOption("--network-caching=5000") media.addOption("--network-caching=5000")
@ -452,6 +461,14 @@ extension VLCPlayerViewController {
} }
viewModel = newViewModel viewModel = newViewModel
if viewModel.streamType == .direct {
LogManager.shared.log.debug("Player set up with direct play stream for item: \(viewModel.item.id ?? "--")")
} else if viewModel.streamType == .transcode && Defaults[.Experimental.forceDirectPlay] {
LogManager.shared.log.debug("Player set up with forced direct stream for item: \(viewModel.item.id ?? "--")")
} else {
LogManager.shared.log.debug("Player set up with transcoded stream for item: \(viewModel.item.id ?? "--")")
}
} }
// MARK: startPlayback // MARK: startPlayback

View File

@ -141,7 +141,8 @@ struct tvOSVLCOverlay_Previews: PreviewProvider {
static let videoPlayerViewModel = VideoPlayerViewModel(item: BaseItemDto(), static let videoPlayerViewModel = VideoPlayerViewModel(item: BaseItemDto(),
title: "Glorious Purpose", title: "Glorious Purpose",
subtitle: "Loki - S1E1", subtitle: "Loki - S1E1",
streamURL: URL(string: "www.apple.com")!, directStreamURL: URL(string: "www.apple.com")!,
transcodedStreamURL: nil,
streamType: .direct, streamType: .direct,
response: PlaybackInfoResponse(), response: PlaybackInfoResponse(),
audioStreams: [MediaStream(displayTitle: "English", index: -1)], audioStreams: [MediaStream(displayTitle: "English", index: -1)],

View File

@ -11,6 +11,8 @@ import SwiftUI
struct ExperimentalSettingsView: View { struct ExperimentalSettingsView: View {
@Default(.Experimental.forceDirectPlay)
var forceDirectPlay
@Default(.Experimental.syncSubtitleStateWithAdjacent) @Default(.Experimental.syncSubtitleStateWithAdjacent)
var syncSubtitleStateWithAdjacent var syncSubtitleStateWithAdjacent
@ -18,6 +20,8 @@ struct ExperimentalSettingsView: View {
Form { Form {
Section { Section {
Toggle("Force Direct Play", isOn: $forceDirectPlay)
Toggle("Sync Subtitles with Adjacent Episodes", isOn: $syncSubtitleStateWithAdjacent) Toggle("Sync Subtitles with Adjacent Episodes", isOn: $syncSubtitleStateWithAdjacent)
} header: { } header: {

View File

@ -383,7 +383,8 @@ struct VLCPlayerCompactOverlayView_Previews: PreviewProvider {
static let videoPlayerViewModel = VideoPlayerViewModel(item: BaseItemDto(), static let videoPlayerViewModel = VideoPlayerViewModel(item: BaseItemDto(),
title: "Glorious Purpose", title: "Glorious Purpose",
subtitle: "Loki - S1E1", subtitle: "Loki - S1E1",
streamURL: URL(string: "www.apple.com")!, directStreamURL: URL(string: "www.apple.com")!,
transcodedStreamURL: nil,
streamType: .direct, streamType: .direct,
response: PlaybackInfoResponse(), response: PlaybackInfoResponse(),
audioStreams: [MediaStream(displayTitle: "English", index: -1)], audioStreams: [MediaStream(displayTitle: "English", index: -1)],

View File

@ -316,7 +316,16 @@ extension VLCPlayerViewController {
lastPlayerTicks = newViewModel.item.userData?.playbackPositionTicks ?? 0 lastPlayerTicks = newViewModel.item.userData?.playbackPositionTicks ?? 0
lastProgressReportTicks = newViewModel.item.userData?.playbackPositionTicks ?? 0 lastProgressReportTicks = newViewModel.item.userData?.playbackPositionTicks ?? 0
let media = VLCMedia(url: newViewModel.streamURL) let media: VLCMedia
if let transcodedURL = newViewModel.transcodedStreamURL,
!Defaults[.Experimental.forceDirectPlay]
{
media = VLCMedia(url: transcodedURL)
} else {
media = VLCMedia(url: newViewModel.directStreamURL)
}
media.addOption("--prefetch-buffer-size=1048576") media.addOption("--prefetch-buffer-size=1048576")
media.addOption("--network-caching=5000") media.addOption("--network-caching=5000")
@ -344,11 +353,12 @@ extension VLCPlayerViewController {
viewModel = newViewModel viewModel = newViewModel
switch viewModel.streamType { if viewModel.streamType == .direct {
case .transcode:
LogManager.shared.log.debug("Player set up with transcoded stream for item: \(viewModel.item.id ?? "--")")
case .direct:
LogManager.shared.log.debug("Player set up with direct play stream for item: \(viewModel.item.id ?? "--")") LogManager.shared.log.debug("Player set up with direct play stream for item: \(viewModel.item.id ?? "--")")
} else if viewModel.streamType == .transcode && Defaults[.Experimental.forceDirectPlay] {
LogManager.shared.log.debug("Player set up with forced direct stream for item: \(viewModel.item.id ?? "--")")
} else {
LogManager.shared.log.debug("Player set up with transcoded stream for item: \(viewModel.item.id ?? "--")")
} }
} }