remove hls stream

This commit is contained in:
Ethan Pippin 2022-01-08 18:06:03 -07:00
parent f18b132b15
commit d77f59d048
8 changed files with 61 additions and 237 deletions

View File

@ -41,45 +41,24 @@ extension BaseItemDto {
let defaultSubtitleStream = subtitleStreams.first(where: { $0.index! == mediaSource.defaultSubtitleStreamIndex ?? -1 }) let defaultSubtitleStream = subtitleStreams.first(where: { $0.index! == mediaSource.defaultSubtitleStreamIndex ?? -1 })
let videoStream = mediaSource.mediaStreams!.first(where: { $0.type! == MediaStreamType.video }) // MARK: Stream
let audioCodecs = mediaSource.mediaStreams!.filter({ $0.type! == MediaStreamType.audio }).map({ $0.codec! })
// MARK: basic stream
var streamURL = URLComponents(string: SessionManager.main.currentLogin.server.currentURI)! var streamURL = URLComponents(string: SessionManager.main.currentLogin.server.currentURI)!
streamURL.path = "/Videos/\(self.id!)/stream"
let streamType: ServerStreamType
if let transcodeURL = mediaSource.transcodingUrl {
streamType = .transcode
streamURL.path = transcodeURL
} else {
streamType = .direct
streamURL.path = "/Videos/\(self.id!)/stream"
}
streamURL.addQueryItem(name: "Static", value: "true") streamURL.addQueryItem(name: "Static", value: "true")
streamURL.addQueryItem(name: "MediaSourceId", value: self.id!) streamURL.addQueryItem(name: "MediaSourceId", value: self.id!)
streamURL.addQueryItem(name: "Tag", value: self.etag) streamURL.addQueryItem(name: "Tag", value: self.etag)
streamURL.addQueryItem(name: "MinSegments", value: "6") streamURL.addQueryItem(name: "MinSegments", value: "6")
// MARK: hls stream
var hlsURL = URLComponents(string: SessionManager.main.currentLogin.server.currentURI)!
hlsURL.path = "/videos/\(self.id!)/master.m3u8"
hlsURL.addQueryItem(name: "DeviceId", value: UIDevice.vendorUUIDString)
hlsURL.addQueryItem(name: "MediaSourceId", value: self.id!)
hlsURL.addQueryItem(name: "VideoCodec", value: videoStream?.codec!)
hlsURL.addQueryItem(name: "AudioCodec", value: audioCodecs.joined(separator: ","))
hlsURL.addQueryItem(name: "AudioStreamIndex", value: "\(defaultAudioStream!.index!)")
hlsURL.addQueryItem(name: "VideoBitrate", value: "\(videoStream!.bitRate!)")
hlsURL.addQueryItem(name: "AudioBitrate", value: "\(defaultAudioStream!.bitRate!)")
hlsURL.addQueryItem(name: "PlaySessionId", value: response.playSessionId!)
hlsURL.addQueryItem(name: "TranscodingMaxAudioChannels", value: "6")
hlsURL.addQueryItem(name: "RequireAvc", value: "false")
hlsURL.addQueryItem(name: "Tag", value: mediaSource.eTag!)
hlsURL.addQueryItem(name: "SegmentContainer", value: "ts")
hlsURL.addQueryItem(name: "MinSegments", value: "2")
hlsURL.addQueryItem(name: "BreakOnNonKeyFrames", value: "true")
hlsURL.addQueryItem(name: "TranscodeReasons", value: "VideoCodecNotSupported,AudioCodecNotSupported")
hlsURL.addQueryItem(name: "api_key", value: SessionManager.main.currentLogin.user.accessToken)
if defaultSubtitleStream?.index != nil {
hlsURL.addQueryItem(name: "SubtitleMethod", value: "Encode")
hlsURL.addQueryItem(name: "SubtitleStreamIndex", value: "\(defaultSubtitleStream!.index!)")
}
// MARK: VidoPlayerViewModel Creation // MARK: VidoPlayerViewModel Creation
var subtitle: String? = nil var subtitle: String? = nil
@ -110,7 +89,7 @@ extension BaseItemDto {
title: modifiedSelfItem.name ?? "", title: modifiedSelfItem.name ?? "",
subtitle: subtitle, subtitle: subtitle,
streamURL: streamURL.url!, streamURL: streamURL.url!,
hlsURL: hlsURL.url!, streamType: streamType,
response: response, response: response,
audioStreams: audioStreams, audioStreams: audioStreams,
subtitleStreams: subtitleStreams, subtitleStreams: subtitleStreams,

View File

@ -0,0 +1,15 @@
//
/*
* SwiftFin is subject to the terms of the Mozilla Public
* License, v2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* Copyright 2021 Aiden Vigue & Jellyfin Contributors
*/
import Foundation
enum ServerStreamType {
case direct
case transcode
}

View File

@ -85,12 +85,12 @@ final class VideoPlayerViewModel: ViewModel {
let title: String let title: String
let subtitle: String? let subtitle: String?
let streamURL: URL let streamURL: URL
let hlsURL: URL
let audioStreams: [MediaStream] let audioStreams: [MediaStream]
let subtitleStreams: [MediaStream] let subtitleStreams: [MediaStream]
let overlayType: OverlayType let overlayType: OverlayType
let jumpGesturesEnabled: Bool let jumpGesturesEnabled: Bool
let resumeOffset: Bool let resumeOffset: Bool
let streamType: ServerStreamType
// MARK: Experimental // MARK: Experimental
let syncSubtitleStateWithAdjacent: Bool let syncSubtitleStateWithAdjacent: Bool
@ -141,7 +141,7 @@ final class VideoPlayerViewModel: ViewModel {
title: String, title: String,
subtitle: String?, subtitle: String?,
streamURL: URL, streamURL: URL,
hlsURL: URL, streamType: ServerStreamType,
response: PlaybackInfoResponse, response: PlaybackInfoResponse,
audioStreams: [MediaStream], audioStreams: [MediaStream],
subtitleStreams: [MediaStream], subtitleStreams: [MediaStream],
@ -157,7 +157,7 @@ final class VideoPlayerViewModel: ViewModel {
self.title = title self.title = title
self.subtitle = subtitle self.subtitle = subtitle
self.streamURL = streamURL self.streamURL = streamURL
self.hlsURL = hlsURL self.streamType = streamType
self.response = response self.response = response
self.audioStreams = audioStreams self.audioStreams = audioStreams
self.subtitleStreams = subtitleStreams self.subtitleStreams = subtitleStreams

View File

@ -1,164 +0,0 @@
//
/*
* SwiftFin is subject to the terms of the Mozilla Public
* License, v2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* Copyright 2021 Aiden Vigue & Jellyfin Contributors
*/
import AVKit
import Combine
import JellyfinAPI
import UIKit
class NativePlayerViewController: AVPlayerViewController {
let viewModel: VideoPlayerViewModel
var timeObserverToken: Any?
var lastProgressTicks: Int64 = 0
private var cancellables = Set<AnyCancellable>()
init(viewModel: VideoPlayerViewModel) {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)
let player = AVPlayer(url: viewModel.hlsURL)
player.appliesMediaSelectionCriteriaAutomatically = false
player.currentItem?.externalMetadata = createMetadata()
player.currentItem?.navigationMarkerGroups = createNavigationMarkerGroups()
// let chevron = UIImage(systemName: "chevron.right.circle.fill")!
// let testAction = UIAction(title: "Next", image: chevron) { action in
// SessionAPI.sendSystemCommand(sessionId: viewModel.response.playSessionId!, command: .setSubtitleStreamIndex)
// .sink { completion in
// print(completion)
// } receiveValue: { _ in
// print("idk but we're here")
// }
// .store(in: &self.cancellables)
// }
// self.transportBarCustomMenuItems = [testAction]
// self.infoViewActions.append(testAction)
let timeScale = CMTimeScale(NSEC_PER_SEC)
let time = CMTime(seconds: 5, preferredTimescale: timeScale)
timeObserverToken = player.addPeriodicTimeObserver(forInterval: time, queue: .main) { [weak self] time in
// print("Timer timed: \(time)")
if time.seconds != 0 {
self?.sendProgressReport(seconds: time.seconds)
}
}
self.player = player
self.allowsPictureInPicturePlayback = true
self.player?.allowsExternalPlayback = true
}
private func createMetadata() -> [AVMetadataItem] {
let allMetadata: [AVMetadataIdentifier: Any] = [
.commonIdentifierTitle: viewModel.title,
.iTunesMetadataTrackSubTitle: viewModel.subtitle ?? "",
.commonIdentifierArtwork: UIImage(data: try! Data(contentsOf: viewModel.item.getBackdropImage(maxWidth: 200)))?.pngData() as Any,
.commonIdentifierDescription: viewModel.item.overview ?? "",
.iTunesMetadataContentRating: viewModel.item.officialRating ?? "",
.quickTimeMetadataGenre: viewModel.item.genres?.first ?? ""
]
return allMetadata.compactMap { createMetadataItem(for:$0, value:$1) }
}
private func createMetadataItem(for identifier: AVMetadataIdentifier,
value: Any) -> AVMetadataItem {
let item = AVMutableMetadataItem()
item.identifier = identifier
item.value = value as? NSCopying & NSObjectProtocol
// Specify "und" to indicate an undefined language.
item.extendedLanguageTag = "und"
return item.copy() as! AVMetadataItem
}
private func createNavigationMarkerGroups() -> [AVNavigationMarkersGroup] {
guard let chapters = viewModel.item.chapters else { return [] }
var metadataGroups: [AVTimedMetadataGroup] = []
// TODO: Determine range between chapters
chapters.forEach { chapterInfo in
var chapterMetadata: [AVMetadataItem] = []
let titleItem = createMetadataItem(for: .commonIdentifierTitle, value: chapterInfo.name ?? "No Name")
chapterMetadata.append(titleItem)
let imageItem = createMetadataItem(for: .commonIdentifierArtwork, value: UIImage(data: try! Data(contentsOf: viewModel.item.getBackdropImage(maxWidth: 200)))?.pngData() as Any)
chapterMetadata.append(imageItem)
let startTime = CMTimeMake(value: chapterInfo.startPositionTicks ?? 0, timescale: 10_000_000)
let endTime = CMTimeMake(value: (chapterInfo.startPositionTicks ?? 0) + 50_000_000, timescale: 10_000_000)
let timeRange = CMTimeRangeFromTimeToTime(start: startTime, end: endTime)
metadataGroups.append(AVTimedMetadataGroup(items: chapterMetadata, timeRange: timeRange))
}
return [AVNavigationMarkersGroup(title: nil, timedNavigationMarkers: metadataGroups)]
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
stop()
removePeriodicTimeObserver()
}
func removePeriodicTimeObserver() {
if let timeObserverToken = timeObserverToken {
player?.removeTimeObserver(timeObserverToken)
self.timeObserverToken = nil
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
player?.seek(to: CMTimeMake(value: viewModel.item.userData?.playbackPositionTicks ?? 0, timescale: 10_000_000), toleranceBefore: CMTimeMake(value: 5, timescale: 1), toleranceAfter: CMTimeMake(value: 5, timescale: 1), completionHandler: { _ in
self.play()
})
}
private func play() {
player?.play()
// viewModel.sendPlayReport(startTimeTicks: viewModel.item.userData?.playbackPositionTicks ?? 0)
viewModel.sendPlayReport()
}
private func sendProgressReport(seconds: Double) {
// viewModel.sendProgressReport(ticks: Int64(seconds) * 10_000_000)
viewModel.sendProgressReport()
}
private func stop() {
self.player?.pause()
viewModel.sendStopReport()
// viewModel.sendStopReport(ticks: 10_000_000)
}
}

View File

@ -10,22 +10,6 @@
import UIKit import UIKit
import SwiftUI import SwiftUI
struct NativePlayerView: UIViewControllerRepresentable {
let viewModel: VideoPlayerViewModel
typealias UIViewControllerType = NativePlayerViewController
func makeUIViewController(context: Context) -> NativePlayerViewController {
return NativePlayerViewController(viewModel: viewModel)
}
func updateUIViewController(_ uiViewController: NativePlayerViewController, context: Context) {
}
}
struct VLCPlayerView: UIViewControllerRepresentable { struct VLCPlayerView: UIViewControllerRepresentable {
let viewModel: VideoPlayerViewModel let viewModel: VideoPlayerViewModel

View File

@ -140,7 +140,7 @@ struct tvOSVLCOverlay_Previews: PreviewProvider {
title: "Glorious Purpose", title: "Glorious Purpose",
subtitle: "Loki - S1E1", subtitle: "Loki - S1E1",
streamURL: URL(string: "www.apple.com")!, streamURL: URL(string: "www.apple.com")!,
hlsURL: URL(string: "www.apple.com")!, streamType: .direct,
response: PlaybackInfoResponse(), response: PlaybackInfoResponse(),
audioStreams: [MediaStream(displayTitle: "English", index: -1)], audioStreams: [MediaStream(displayTitle: "English", index: -1)],
subtitleStreams: [MediaStream(displayTitle: "None", index: -1)], subtitleStreams: [MediaStream(displayTitle: "None", index: -1)],

View File

@ -274,6 +274,8 @@
E122A9132788EAAD0060FA63 /* MediaStreamExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = E122A9122788EAAD0060FA63 /* MediaStreamExtension.swift */; }; E122A9132788EAAD0060FA63 /* MediaStreamExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = E122A9122788EAAD0060FA63 /* MediaStreamExtension.swift */; };
E122A9142788EAAD0060FA63 /* MediaStreamExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = E122A9122788EAAD0060FA63 /* MediaStreamExtension.swift */; }; E122A9142788EAAD0060FA63 /* MediaStreamExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = E122A9122788EAAD0060FA63 /* MediaStreamExtension.swift */; };
E1267D3E271A1F46003C492E /* PreferenceUIHostingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1267D3D271A1F46003C492E /* PreferenceUIHostingController.swift */; }; E1267D3E271A1F46003C492E /* PreferenceUIHostingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1267D3D271A1F46003C492E /* PreferenceUIHostingController.swift */; };
E126F741278A656C00A522BF /* ServerStreamType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E126F740278A656C00A522BF /* ServerStreamType.swift */; };
E126F742278A656C00A522BF /* ServerStreamType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E126F740278A656C00A522BF /* ServerStreamType.swift */; };
E131691726C583BC0074BFEE /* LogConstructor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E131691626C583BC0074BFEE /* LogConstructor.swift */; }; E131691726C583BC0074BFEE /* LogConstructor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E131691626C583BC0074BFEE /* LogConstructor.swift */; };
E131691826C583BC0074BFEE /* LogConstructor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E131691626C583BC0074BFEE /* LogConstructor.swift */; }; E131691826C583BC0074BFEE /* LogConstructor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E131691626C583BC0074BFEE /* LogConstructor.swift */; };
E131691926C583BC0074BFEE /* LogConstructor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E131691626C583BC0074BFEE /* LogConstructor.swift */; }; E131691926C583BC0074BFEE /* LogConstructor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E131691626C583BC0074BFEE /* LogConstructor.swift */; };
@ -384,7 +386,6 @@
E1C812C3277A8E5D00918266 /* VLCPlayerOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1C812BB277A8E5D00918266 /* VLCPlayerOverlayView.swift */; }; E1C812C3277A8E5D00918266 /* VLCPlayerOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1C812BB277A8E5D00918266 /* VLCPlayerOverlayView.swift */; };
E1C812C5277A90B200918266 /* URLComponentsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1C812C4277A90B200918266 /* URLComponentsExtensions.swift */; }; E1C812C5277A90B200918266 /* URLComponentsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1C812C4277A90B200918266 /* URLComponentsExtensions.swift */; };
E1C812CA277AE40900918266 /* PlayerOverlayDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1C812C6277AE40900918266 /* PlayerOverlayDelegate.swift */; }; E1C812CA277AE40900918266 /* PlayerOverlayDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1C812C6277AE40900918266 /* PlayerOverlayDelegate.swift */; };
E1C812CB277AE40900918266 /* NativePlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1C812C7277AE40900918266 /* NativePlayerViewController.swift */; };
E1C812CC277AE40A00918266 /* VideoPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1C812C8277AE40900918266 /* VideoPlayerView.swift */; }; E1C812CC277AE40A00918266 /* VideoPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1C812C8277AE40900918266 /* VideoPlayerView.swift */; };
E1C812CD277AE40A00918266 /* VideoPlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1C812C9277AE40900918266 /* VideoPlayerViewModel.swift */; }; E1C812CD277AE40A00918266 /* VideoPlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1C812C9277AE40900918266 /* VideoPlayerViewModel.swift */; };
E1C812CE277AE43100918266 /* VideoPlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1C812C9277AE40900918266 /* VideoPlayerViewModel.swift */; }; E1C812CE277AE43100918266 /* VideoPlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1C812C9277AE40900918266 /* VideoPlayerViewModel.swift */; };
@ -649,6 +650,7 @@
E11D224127378428003F9CB3 /* ServerDetailCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerDetailCoordinator.swift; sourceTree = "<group>"; }; E11D224127378428003F9CB3 /* ServerDetailCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerDetailCoordinator.swift; sourceTree = "<group>"; };
E122A9122788EAAD0060FA63 /* MediaStreamExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaStreamExtension.swift; sourceTree = "<group>"; }; E122A9122788EAAD0060FA63 /* MediaStreamExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaStreamExtension.swift; sourceTree = "<group>"; };
E1267D3D271A1F46003C492E /* PreferenceUIHostingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferenceUIHostingController.swift; sourceTree = "<group>"; }; E1267D3D271A1F46003C492E /* PreferenceUIHostingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferenceUIHostingController.swift; sourceTree = "<group>"; };
E126F740278A656C00A522BF /* ServerStreamType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerStreamType.swift; sourceTree = "<group>"; };
E131691626C583BC0074BFEE /* LogConstructor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogConstructor.swift; sourceTree = "<group>"; }; E131691626C583BC0074BFEE /* LogConstructor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogConstructor.swift; sourceTree = "<group>"; };
E1384943278036C70024FB48 /* VLCPlayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VLCPlayerViewController.swift; sourceTree = "<group>"; }; E1384943278036C70024FB48 /* VLCPlayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VLCPlayerViewController.swift; sourceTree = "<group>"; };
E13D02842788B634000FCB04 /* Swiftfin.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Swiftfin.entitlements; sourceTree = "<group>"; }; E13D02842788B634000FCB04 /* Swiftfin.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Swiftfin.entitlements; sourceTree = "<group>"; };
@ -710,7 +712,6 @@
E1C812BB277A8E5D00918266 /* VLCPlayerOverlayView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VLCPlayerOverlayView.swift; sourceTree = "<group>"; }; E1C812BB277A8E5D00918266 /* VLCPlayerOverlayView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VLCPlayerOverlayView.swift; sourceTree = "<group>"; };
E1C812C4277A90B200918266 /* URLComponentsExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLComponentsExtensions.swift; sourceTree = "<group>"; }; E1C812C4277A90B200918266 /* URLComponentsExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLComponentsExtensions.swift; sourceTree = "<group>"; };
E1C812C6277AE40900918266 /* PlayerOverlayDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayerOverlayDelegate.swift; sourceTree = "<group>"; }; E1C812C6277AE40900918266 /* PlayerOverlayDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayerOverlayDelegate.swift; sourceTree = "<group>"; };
E1C812C7277AE40900918266 /* NativePlayerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NativePlayerViewController.swift; sourceTree = "<group>"; };
E1C812C8277AE40900918266 /* VideoPlayerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoPlayerView.swift; sourceTree = "<group>"; }; E1C812C8277AE40900918266 /* VideoPlayerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoPlayerView.swift; sourceTree = "<group>"; };
E1C812C9277AE40900918266 /* VideoPlayerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoPlayerViewModel.swift; sourceTree = "<group>"; }; E1C812C9277AE40900918266 /* VideoPlayerViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoPlayerViewModel.swift; sourceTree = "<group>"; };
E1C812D0277AE4E300918266 /* tvOSVideoPlayerCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = tvOSVideoPlayerCoordinator.swift; sourceTree = "<group>"; }; E1C812D0277AE4E300918266 /* tvOSVideoPlayerCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = tvOSVideoPlayerCoordinator.swift; sourceTree = "<group>"; };
@ -816,7 +817,6 @@
5310694F2684E7EE00CFFDBA /* VideoPlayer */ = { 5310694F2684E7EE00CFFDBA /* VideoPlayer */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
E1C812C7277AE40900918266 /* NativePlayerViewController.swift */,
E1C812C6277AE40900918266 /* PlayerOverlayDelegate.swift */, E1C812C6277AE40900918266 /* PlayerOverlayDelegate.swift */,
E178859C2780F5300094FBCF /* tvOSSLider */, E178859C2780F5300094FBCF /* tvOSSLider */,
E17885A7278130690094FBCF /* tvOSOverlay */, E17885A7278130690094FBCF /* tvOSOverlay */,
@ -850,7 +850,7 @@
E13DD3F82717E961009D4DAF /* UserListViewModel.swift */, E13DD3F82717E961009D4DAF /* UserListViewModel.swift */,
E13DD3EB27178A54009D4DAF /* UserSignInViewModel.swift */, E13DD3EB27178A54009D4DAF /* UserSignInViewModel.swift */,
09389CC626819B4500AE350E /* VideoPlayerModel.swift */, 09389CC626819B4500AE350E /* VideoPlayerModel.swift */,
E1C812C9277AE40900918266 /* VideoPlayerViewModel.swift */, E126F73F278A655300A522BF /* VideoPlayerViewModel */,
625CB57B2678CE1000530A6E /* ViewModel.swift */, 625CB57B2678CE1000530A6E /* ViewModel.swift */,
); );
path = ViewModels; path = ViewModels;
@ -1362,6 +1362,15 @@
path = Views; path = Views;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
E126F73F278A655300A522BF /* VideoPlayerViewModel */ = {
isa = PBXGroup;
children = (
E126F740278A656C00A522BF /* ServerStreamType.swift */,
E1C812C9277AE40900918266 /* VideoPlayerViewModel.swift */,
);
path = VideoPlayerViewModel;
sourceTree = "<group>";
};
E13DD3BB27163C3E009D4DAF /* App */ = { E13DD3BB27163C3E009D4DAF /* App */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -2041,7 +2050,6 @@
E11D224327378428003F9CB3 /* ServerDetailCoordinator.swift in Sources */, E11D224327378428003F9CB3 /* ServerDetailCoordinator.swift in Sources */,
E1D4BF8B2719D3D000A11E64 /* BasicAppSettingsCoordinator.swift in Sources */, E1D4BF8B2719D3D000A11E64 /* BasicAppSettingsCoordinator.swift in Sources */,
E1E5D53B2783A80900692DFE /* CinematicItemViewTopRow.swift in Sources */, E1E5D53B2783A80900692DFE /* CinematicItemViewTopRow.swift in Sources */,
E1C812CB277AE40900918266 /* NativePlayerViewController.swift in Sources */,
E13DD3FA2717E961009D4DAF /* UserListViewModel.swift in Sources */, E13DD3FA2717E961009D4DAF /* UserListViewModel.swift in Sources */,
C40CD926271F8D1E000FB198 /* MovieLibrariesViewModel.swift in Sources */, C40CD926271F8D1E000FB198 /* MovieLibrariesViewModel.swift in Sources */,
62E632DE267D2E170063E547 /* LatestMediaViewModel.swift in Sources */, 62E632DE267D2E170063E547 /* LatestMediaViewModel.swift in Sources */,
@ -2061,6 +2069,7 @@
E1384944278036C70024FB48 /* VLCPlayerViewController.swift in Sources */, E1384944278036C70024FB48 /* VLCPlayerViewController.swift in Sources */,
091B5A8E268315D400D78B61 /* UDPBroadCastConnection.swift in Sources */, 091B5A8E268315D400D78B61 /* UDPBroadCastConnection.swift in Sources */,
E10EAA50277BBCC4000269ED /* CGSizeExtensions.swift in Sources */, E10EAA50277BBCC4000269ED /* CGSizeExtensions.swift in Sources */,
E126F742278A656C00A522BF /* ServerStreamType.swift in Sources */,
E1E5D5422783B33900692DFE /* PortraitItemsRowView.swift in Sources */, E1E5D5422783B33900692DFE /* PortraitItemsRowView.swift in Sources */,
E1FCD08926C35A0D007C8DCF /* NetworkError.swift in Sources */, E1FCD08926C35A0D007C8DCF /* NetworkError.swift in Sources */,
531690ED267ABF46005D8AB9 /* ContinueWatchingView.swift in Sources */, 531690ED267ABF46005D8AB9 /* ContinueWatchingView.swift in Sources */,
@ -2322,6 +2331,7 @@
5389277C263CC3DB0035E14B /* BlurHashDecode.swift in Sources */, 5389277C263CC3DB0035E14B /* BlurHashDecode.swift in Sources */,
E1D4BF8A2719D3D000A11E64 /* BasicAppSettingsCoordinator.swift in Sources */, E1D4BF8A2719D3D000A11E64 /* BasicAppSettingsCoordinator.swift in Sources */,
E13DD3F92717E961009D4DAF /* UserListViewModel.swift in Sources */, E13DD3F92717E961009D4DAF /* UserListViewModel.swift in Sources */,
E126F741278A656C00A522BF /* ServerStreamType.swift in Sources */,
539B2DA5263BA5B8007FF1A4 /* SettingsView.swift in Sources */, 539B2DA5263BA5B8007FF1A4 /* SettingsView.swift in Sources */,
5338F74E263B61370014BF09 /* ConnectToServerView.swift in Sources */, 5338F74E263B61370014BF09 /* ConnectToServerView.swift in Sources */,
09389CC726819B4600AE350E /* VideoPlayerModel.swift in Sources */, 09389CC726819B4600AE350E /* VideoPlayerModel.swift in Sources */,

View File

@ -382,21 +382,21 @@ struct VLCPlayerOverlayView: View {
struct VLCPlayerCompactOverlayView_Previews: PreviewProvider { 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")!, streamURL: URL(string: "www.apple.com")!,
hlsURL: URL(string: "www.apple.com")!, streamType: .direct,
response: PlaybackInfoResponse(), response: PlaybackInfoResponse(),
audioStreams: [MediaStream(displayTitle: "English", index: -1)], audioStreams: [MediaStream(displayTitle: "English", index: -1)],
subtitleStreams: [MediaStream(displayTitle: "None", index: -1)], subtitleStreams: [MediaStream(displayTitle: "None", index: -1)],
selectedAudioStreamIndex: -1, selectedAudioStreamIndex: -1,
selectedSubtitleStreamIndex: -1, selectedSubtitleStreamIndex: -1,
subtitlesEnabled: true, subtitlesEnabled: true,
autoplayEnabled: false, autoplayEnabled: false,
overlayType: .compact, overlayType: .compact,
shouldShowPlayPreviousItem: true, shouldShowPlayPreviousItem: true,
shouldShowPlayNextItem: true, shouldShowPlayNextItem: true,
shouldShowAutoPlay: true) shouldShowAutoPlay: true)
static var previews: some View { static var previews: some View {
ZStack { ZStack {