Auto stash before merge of "main" and "Jellyfin/main"

This commit is contained in:
Aiden Vigue 2021-05-27 13:25:20 -04:00
parent 33631e7a23
commit bd386b4e45
No known key found for this signature in database
GPG Key ID: E7570472648F4544
4 changed files with 190 additions and 13 deletions

View File

@ -40,6 +40,7 @@
53E4E647263F6CF100F67C6B /* LibraryFilterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53E4E646263F6CF100F67C6B /* LibraryFilterView.swift */; };
53E4E649263F725B00F67C6B /* MultiSelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53E4E648263F725B00F67C6B /* MultiSelector.swift */; };
53EE24E6265060780068F029 /* LibrarySearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53EE24E5265060780068F029 /* LibrarySearchView.swift */; };
53F8377D265FF67C00F456B3 /* VideoPlayerSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F8377C265FF67C00F456B3 /* VideoPlayerSettingsView.swift */; };
53FF7F2A263CF3F500585C35 /* LatestMediaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53FF7F29263CF3F500585C35 /* LatestMediaView.swift */; };
AE8C3154265D60BF008AA076 /* SettingsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE8C3153265D60BF008AA076 /* SettingsModel.swift */; };
AE8C3156265D616A008AA076 /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE8C3155265D616A008AA076 /* SettingsViewModel.swift */; };
@ -99,6 +100,7 @@
53E4E646263F6CF100F67C6B /* LibraryFilterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibraryFilterView.swift; sourceTree = "<group>"; };
53E4E648263F725B00F67C6B /* MultiSelector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiSelector.swift; sourceTree = "<group>"; };
53EE24E5265060780068F029 /* LibrarySearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibrarySearchView.swift; sourceTree = "<group>"; };
53F8377C265FF67C00F456B3 /* VideoPlayerSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPlayerSettingsView.swift; sourceTree = "<group>"; };
53FF7F29263CF3F500585C35 /* LatestMediaView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LatestMediaView.swift; sourceTree = "<group>"; };
AE8C3153265D60BF008AA076 /* SettingsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsModel.swift; sourceTree = "<group>"; };
AE8C3155265D616A008AA076 /* SettingsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = "<group>"; };
@ -198,6 +200,7 @@
535BAEA4264A151C005FA86D /* VideoPlayer.swift */,
539B2DA4263BA5B8007FF1A4 /* SettingsView.swift */,
53313B8F265EEA6D00947AA3 /* VideoPlayer.storyboard */,
53F8377C265FF67C00F456B3 /* VideoPlayerSettingsView.swift */,
);
path = Views;
sourceTree = "<group>";
@ -322,6 +325,7 @@
5377CBFE263B596B003A4E83 /* PersistenceController.swift in Sources */,
5389276E263C25100035E14B /* ContinueWatchingView.swift in Sources */,
535BAE9F2649E569005FA86D /* ItemView.swift in Sources */,
53F8377D265FF67C00F456B3 /* VideoPlayerSettingsView.swift in Sources */,
53987CA426572C1300E7EA70 /* SeasonItemView.swift in Sources */,
53192D5D265AA78A008A4215 /* DeviceProfileBuilder.swift in Sources */,
AE8C3154265D60BF008AA076 /* SettingsModel.swift in Sources */,

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="ipad11_0rounded" orientation="portrait" layout="fullscreen" appearance="light"/>
<device id="retina6_5" orientation="landscape" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<capability name="Image references" minToolsVersion="12.0"/>
@ -14,10 +14,10 @@
<objects>
<viewController storyboardIdentifier="VideoPlayer" id="Y6W-OH-hqX" customClass="PlayerViewController" customModule="JellyfinPlayer" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" autoresizesSubviews="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IQg-r0-AeH">
<rect key="frame" x="0.0" y="0.0" width="834" height="1194"/>
<rect key="frame" x="0.0" y="0.0" width="896" height="414"/>
<subviews>
<view autoresizesSubviews="NO" tag="1" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Tsh-rC-BwO" userLabel="VideoContentView">
<rect key="frame" x="-13" y="0.0" width="860" height="1194"/>
<rect key="frame" x="31" y="0.0" width="834" height="414"/>
<viewLayoutGuide key="safeArea" id="aVY-BC-PZU"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<gestureRecognizers/>
@ -26,10 +26,10 @@
</connections>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Qcb-Fb-qZl" userLabel="VideoControlsView">
<rect key="frame" x="0.0" y="0.0" width="834" height="1194"/>
<rect key="frame" x="0.0" y="0.0" width="896" height="414"/>
<subviews>
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="e9f-8l-RdN" userLabel="SeekSlider">
<rect key="frame" x="50" y="1135" width="627" height="31"/>
<rect key="frame" x="50" y="355" width="689" height="31"/>
<color key="tintColor" red="0.66666666666666663" green="0.36078431372549019" blue="0.76470588235294112" alpha="1" colorSpace="calibratedRGB"/>
<color key="thumbTintColor" red="0.66666666666666663" green="0.36078431372549019" blue="0.76470588235294112" alpha="1" colorSpace="calibratedRGB"/>
<connections>
@ -39,7 +39,7 @@
</connections>
</slider>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="-:--:--" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qft-iu-f1z">
<rect key="frame" x="704" y="1133" width="91" height="34"/>
<rect key="frame" x="766" y="353" width="91" height="34"/>
<constraints>
<constraint firstAttribute="width" constant="91" id="LbL-h0-EYA"/>
<constraint firstAttribute="height" constant="34" id="OkD-Dr-Ina"/>
@ -49,7 +49,7 @@
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="t2L-Oz-fe9" userLabel="MainActionButton">
<rect key="frame" x="375.5" y="555.5" width="83" height="83"/>
<rect key="frame" x="406.66666666666669" y="165.66666666666666" width="83" height="83"/>
<constraints>
<constraint firstAttribute="width" constant="83" id="PdD-nW-y9r"/>
<constraint firstAttribute="height" constant="83" id="e9j-PI-Ic4"/>
@ -81,7 +81,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bYM-Xp-bZO">
<rect key="frame" x="182" y="559" width="75" height="76"/>
<rect key="frame" x="213" y="169" width="75" height="76"/>
<constraints>
<constraint firstAttribute="height" constant="76" id="5lC-V1-lHH"/>
<constraint firstAttribute="width" constant="75" id="IPn-pO-Rxo"/>
@ -95,7 +95,7 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="An8-jF-FAY">
<rect key="frame" x="577" y="559" width="75" height="76"/>
<rect key="frame" x="608" y="169" width="75" height="76"/>
<constraints>
<constraint firstAttribute="height" constant="76" id="huv-QZ-HSc"/>
<constraint firstAttribute="width" constant="75" id="uPN-A8-EV1"/>
@ -109,16 +109,19 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="riN-y1-ABZ">
<rect key="frame" x="739" y="24" width="56" height="56"/>
<rect key="frame" x="801" y="24" width="56" height="56"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<state key="normal" image="gear" catalog="system">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<preferredSymbolConfiguration key="preferredSymbolConfiguration" configurationType="pointSize" pointSize="23"/>
</state>
<connections>
<action selector="settingsButtonTapped:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="NeC-px-2TY"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Loading" textAlignment="center" lineBreakMode="tailTruncation" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="o8N-R1-DhT">
<rect key="frame" x="106" y="-367" width="622" height="838"/>
<rect key="frame" x="106" y="23.333333333333332" width="684" height="57.666666666666671"/>
<accessibility key="accessibilityConfiguration">
<accessibilityTraits key="traits" staticText="YES" header="YES"/>
</accessibility>

View File

@ -39,7 +39,7 @@ protocol PlayerViewControllerDelegate: AnyObject {
func exitPlayer(_ viewController: PlayerViewController)
}
class PlayerViewController: UIViewController, VLCMediaDelegate, VLCMediaPlayerDelegate {
class PlayerViewController: UIViewController, VLCMediaDelegate, VLCMediaPlayerDelegate, VideoPlayerSettingsDelegate {
weak var delegate: PlayerViewControllerDelegate?
@ -153,6 +153,32 @@ class PlayerViewController: UIViewController, VLCMediaDelegate, VLCMediaPlayerDe
}
}
@IBAction func settingsButtonTapped(_ sender: UIButton) {
let optionsVC = VideoPlayerSettingsView()
optionsVC.delegate = self;
optionsVC.subtitles = subtitleTrackArray
optionsVC.audioTracks = audioTrackArray
optionsVC.currentSubtitleTrack = selectedCaptionTrack
optionsVC.currentAudioTrack = selectedAudioTrack
// Use the popover presentation style for your view controller.
optionsVC.modalPresentationStyle = .popover
// Specify the anchor point for the popover.
optionsVC.popoverPresentationController?.sourceView = playerSettingsButton
// Present the view controller (in a popover).
self.present(optionsVC, animated: true) {
print("popover visible, pause playback")
self.mediaPlayer.pause()
self.mainActionButton.setImage(UIImage(systemName: "play"), for: .normal)
}
}
func settingsPopoverDismissed() {
self.mediaPlayer.play()
self.mainActionButton.setImage(UIImage(systemName: "pause"), for: .normal)
}
override func viewDidLoad() {
super.viewDidLoad()
@ -301,6 +327,15 @@ class PlayerViewController: UIViewController, VLCMediaDelegate, VLCMediaPlayerDe
self.tabBarController?.tabBar.isHidden = true;
}
//MARK: VideoPlayerSettings Delegate
func subtitleTrackChanged(newTrackID: Int32) {
mediaPlayer.currentVideoSubTitleIndex = newTrackID
}
func audioTrackChanged(newTrackID: Int32) {
mediaPlayer.currentAudioTrackIndex = newTrackID
}
//MARK: VLCMediaPlayer Delegates
func mediaPlayerStateChanged(_ aNotification: Notification!) {
@ -325,7 +360,6 @@ class PlayerViewController: UIViewController, VLCMediaDelegate, VLCMediaPlayerDe
case .buffering :
print("Video is buffering)")
sendProgressReport(eventName: "pause")
delegate?.showLoadingView(self)
mediaPlayer.pause()
usleep(10000)
@ -345,6 +379,7 @@ class PlayerViewController: UIViewController, VLCMediaDelegate, VLCMediaPlayerDe
let time = mediaPlayer.position;
if(time != lastTime) {
paused = false;
mainActionButton.setImage(UIImage(systemName: "pause"), for: .normal)
seekSlider.setValue(mediaPlayer.position, animated: true)
delegate?.hideLoadingView(self)

View File

@ -0,0 +1,135 @@
//
// VideoPlayerSettingsView.swift
// JellyfinPlayer
//
// Created by Aiden Vigue on 5/27/21.
//
import Foundation
import UIKit
import SwiftUI
import Combine
enum SettingsChangedEventTypes {
case subTrackChanged
case audioTrackChanged
}
struct settingsChangedEvent {
let eventType: SettingsChangedEventTypes
let payload: AnyObject
}
protocol VideoPlayerSettingsDelegate: AnyObject {
func subtitleTrackChanged(newTrackID: Int32)
func audioTrackChanged(newTrackID: Int32)
func settingsPopoverDismissed()
}
class SettingsViewDelegate: ObservableObject {
var subtitlesDidChange = PassthroughSubject<SettingsViewDelegate, Never>()
var subtitleTrackID: Int32 = 0 {
didSet {
self.subtitlesDidChange.send(self)
}
}
var audioTrackDidChange = PassthroughSubject<SettingsViewDelegate, Never>()
var audioTrackID: Int32 = 0 {
didSet {
self.audioTrackDidChange.send(self)
}
}
var shouldClose = PassthroughSubject<SettingsViewDelegate, Never>()
var close: Bool = false {
didSet {
self.shouldClose.send(self)
}
}
}
class VideoPlayerSettingsView: UIViewController {
private var ctntView: VideoPlayerSettings!
private var contentViewDelegate: SettingsViewDelegate = SettingsViewDelegate()
weak var delegate: VideoPlayerSettingsDelegate?
private var subChangePublisher: AnyCancellable?
private var audioChangePublisher: AnyCancellable?
private var shouldClosePublisher: AnyCancellable?
var subtitles: [Subtitle] = []
var audioTracks: [AudioTrack] = []
var currentSubtitleTrack: Int32 = -1;
var currentAudioTrack: Int32 = 0;
override func viewDidLoad() {
super.viewDidLoad()
contentViewDelegate.audioTrackID = currentAudioTrack;
contentViewDelegate.subtitleTrackID = currentSubtitleTrack;
ctntView = VideoPlayerSettings(delegate: self.contentViewDelegate, subtitles: self.subtitles, audioTracks: self.audioTracks)
let contentView = UIHostingController(rootView: ctntView)
self.view.addSubview(contentView.view)
contentView.view.translatesAutoresizingMaskIntoConstraints = false;
contentView.view.topAnchor.constraint(equalTo: view.topAnchor).isActive = true;
contentView.view.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true;
contentView.view.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true;
contentView.view.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true;
self.subChangePublisher = self.contentViewDelegate.subtitlesDidChange.sink { suiDelegate in
self.delegate?.subtitleTrackChanged(newTrackID: suiDelegate.subtitleTrackID)
}
self.audioChangePublisher = self.contentViewDelegate.audioTrackDidChange.sink { suiDelegate in
self.delegate?.audioTrackChanged(newTrackID: suiDelegate.audioTrackID)
}
self.shouldClosePublisher = self.contentViewDelegate.shouldClose.sink { suiDelegate in
if(suiDelegate.close == true) {
self.delegate?.settingsPopoverDismissed()
self.dismiss(animated: true, completion: nil)
}
}
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
delegate?.settingsPopoverDismissed()
}
}
struct VideoPlayerSettings: View {
@ObservedObject var delegate: SettingsViewDelegate
@State private var subtitles: [Subtitle]
@State private var audioTracks: [AudioTrack]
init(delegate: SettingsViewDelegate, subtitles: [Subtitle], audioTracks: [AudioTrack]) {
self.delegate = delegate
self.subtitles = subtitles
self.audioTracks = audioTracks
print(subtitles)
print(audioTracks)
}
var body: some View {
NavigationView() {
Form() {
Picker("Closed Captions", selection: self.$delegate.subtitleTrackID) {
ForEach(subtitles, id: \.id) { caption in
Text(caption.name).tag(caption.id)
}
}
Picker("Audio Track", selection: self.$delegate.audioTrackID) {
ForEach(audioTracks, id: \.id) { caption in
Text(caption.name).tag(caption.id).lineLimit(1)
}
}
}.navigationTitle("Audio & Captions")
.navigationBarTitleDisplayMode(.inline)
}.navigationViewStyle(StackNavigationViewStyle())
}
}