allow force direct play as a temporary measure
This commit is contained in:
parent
601113f102
commit
13f457f52a
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)],
|
||||||
|
|
|
@ -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: {
|
||||||
|
|
|
@ -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)],
|
||||||
|
|
|
@ -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 ?? "--")")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue