Add custom time skip durations

This commit is contained in:
Ethan Pippin 2021-08-17 23:41:08 -06:00
parent 6f243621c1
commit 4e41863d23
7 changed files with 103 additions and 6 deletions

View File

@ -200,6 +200,8 @@
E131691726C583BC0074BFEE /* 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 */; };
E1F0204E26CCCA74001C1C3B /* VideoPlayerJumpLength.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1F0204D26CCCA74001C1C3B /* VideoPlayerJumpLength.swift */; };
E1F0204F26CCCA74001C1C3B /* VideoPlayerJumpLength.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1F0204D26CCCA74001C1C3B /* VideoPlayerJumpLength.swift */; };
E1FCD08826C35A0D007C8DCF /* NetworkError.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1FCD08726C35A0D007C8DCF /* NetworkError.swift */; };
E1FCD08926C35A0D007C8DCF /* NetworkError.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1FCD08726C35A0D007C8DCF /* NetworkError.swift */; };
E1FCD09626C47118007C8DCF /* ErrorMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1FCD09526C47118007C8DCF /* ErrorMessage.swift */; };
@ -386,6 +388,7 @@
DE5004F745B19E28744A7DE7 /* Pods-JellyfinPlayer tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JellyfinPlayer tvOS.debug.xcconfig"; path = "Target Support Files/Pods-JellyfinPlayer tvOS/Pods-JellyfinPlayer tvOS.debug.xcconfig"; sourceTree = "<group>"; };
E100720626BDABC100CE3E31 /* MediaPlayButtonRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaPlayButtonRowView.swift; sourceTree = "<group>"; };
E131691626C583BC0074BFEE /* LogConstructor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogConstructor.swift; sourceTree = "<group>"; };
E1F0204D26CCCA74001C1C3B /* VideoPlayerJumpLength.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPlayerJumpLength.swift; sourceTree = "<group>"; };
E1FCD08726C35A0D007C8DCF /* NetworkError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkError.swift; sourceTree = "<group>"; };
E1FCD09526C47118007C8DCF /* ErrorMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorMessage.swift; sourceTree = "<group>"; };
EBFE1F64394BCC2EFFF1610D /* Pods_JellyfinPlayer_tvOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_JellyfinPlayer_tvOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@ -575,17 +578,18 @@
532175392671BCED005491E6 /* ViewModels */,
621338912660106C00A81A2A /* Extensions */,
AE8C3157265D6F5E008AA076 /* Resources */,
535870AB2669D8D300D05A09 /* Typings */,
535870AB2669D8D300D05A09 /* Objects */,
);
path = Shared;
sourceTree = "<group>";
};
535870AB2669D8D300D05A09 /* Typings */ = {
535870AB2669D8D300D05A09 /* Objects */ = {
isa = PBXGroup;
children = (
535870AC2669D8DD00D05A09 /* Typings.swift */,
E1F0204D26CCCA74001C1C3B /* VideoPlayerJumpLength.swift */,
);
path = Typings;
path = Objects;
sourceTree = "<group>";
};
536D3D77267BB9650004248C /* Components */ = {
@ -1137,6 +1141,7 @@
09389CC526814E4500AE350E /* DeviceProfileBuilder.swift in Sources */,
535870A62669D8AE00D05A09 /* LazyView.swift in Sources */,
5321753E2671DE9C005491E6 /* Typings.swift in Sources */,
E1F0204F26CCCA74001C1C3B /* VideoPlayerJumpLength.swift in Sources */,
53ABFDEB2679753200886593 /* ConnectToServerView.swift in Sources */,
536D3D76267BA9BB0004248C /* MainTabViewModel.swift in Sources */,
5310695C2684E7EE00CFFDBA /* VideoPlayerViewController.swift in Sources */,
@ -1191,6 +1196,7 @@
091B5A8B2683142E00D78B61 /* UDPBroadCastConnection.swift in Sources */,
6267B3D626710B8900A7371D /* CollectionExtensions.swift in Sources */,
53A089D0264DA9DA00D57806 /* MovieItemView.swift in Sources */,
E1F0204E26CCCA74001C1C3B /* VideoPlayerJumpLength.swift in Sources */,
53649AB1269CFB1900A2D8B7 /* LogManager.swift in Sources */,
62E632E9267D3FF50063E547 /* SeasonItemViewModel.swift in Sources */,
625CB56A2678B71200530A6E /* SplashViewModel.swift in Sources */,

View File

@ -21,6 +21,8 @@ struct SettingsView: View {
@Default(.autoSelectSubtitlesLangCode) var autoSelectSubtitlesLangcode
@Default(.autoSelectAudioLangCode) var autoSelectAudioLangcode
@Default(.appAppearance) var appAppearance
@Default(.videoPlayerJumpForward) var jumpForwardLength
@Default(.videoPlayerJumpBackward) var jumpBackwardLength
@State private var username: String = ""
func onAppear() {
@ -42,6 +44,18 @@ struct SettingsView: View {
Text(bitrate.name).tag(bitrate.value)
}
}
Picker("Jump Forward Length", selection: $jumpForwardLength) {
ForEach(self.viewModel.videoPlayerJumpLengths, id: \.self) { length in
Text(length.label).tag(length.rawValue)
}
}
Picker("Jump Backward Length", selection: $jumpBackwardLength) {
ForEach(self.viewModel.videoPlayerJumpLengths, id: \.self) { length in
Text(length.label).tag(length.rawValue)
}
}
}
Section(header: Text("Accessibility")) {

View File

@ -76,7 +76,15 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe
var subtitleTrackArray: [Subtitle] = []
var audioTrackArray: [AudioTrack] = []
let playbackSpeeds: [Float] = [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0]
var jumpForwardLength: VideoPlayerJumpLength {
let storedJumpForwardLength = Defaults[.videoPlayerJumpForward]
return VideoPlayerJumpLength(rawValue: storedJumpForwardLength)!
}
var jumpBackwardLength: VideoPlayerJumpLength {
let storedJumpBackwardLength = Defaults[.videoPlayerJumpBackward]
return VideoPlayerJumpLength(rawValue: storedJumpBackwardLength)!
}
var manifest: BaseItemDto = BaseItemDto()
var playbackItem = PlaybackItem()
var remoteTimeUpdateTimer: Timer?
@ -161,7 +169,7 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe
@IBAction func jumpBackTapped(_ sender: Any) {
if paused == false {
if playerDestination == .local {
mediaPlayer.jumpBackward(15)
mediaPlayer.jumpBackward(jumpBackwardLength.rawValue)
} else {
self.sendJellyfinCommand(command: "Seek", options: ["position": (remotePositionTicks/10_000_000)-15])
}
@ -171,7 +179,7 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe
@IBAction func jumpForwardTapped(_ sender: Any) {
if paused == false {
if playerDestination == .local {
mediaPlayer.jumpForward(30)
mediaPlayer.jumpForward(jumpForwardLength.rawValue)
} else {
self.sendJellyfinCommand(command: "Seek", options: ["position": (remotePositionTicks/10_000_000)+30])
}
@ -475,6 +483,7 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe
mediaPlayer.drawable = videoContentView
setupMediaPlayer()
setupJumpLengthButtons()
}
func setupMediaPlayer() {
@ -607,6 +616,12 @@ class PlayerViewController: UIViewController, GCKDiscoveryManagerListener, GCKRe
.store(in: &cancellables)
}
}
private func setupJumpLengthButtons() {
let buttonFont = UIFont.systemFont(ofSize: 35, weight: .regular)
jumpForwardButton.setImage(jumpForwardLength.generateForwardImage(with: buttonFont), for: .normal)
jumpBackButton.setImage(jumpBackwardLength.generateBackwardImage(with: buttonFont), for: .normal)
}
func setupTracksForPreferredDefaults() {
subtitleTrackArray.forEach { subtitle in

View File

@ -17,4 +17,6 @@ extension Defaults.Keys {
static let autoSelectSubtitlesLangCode = Key<String>("AutoSelectSubtitlesLangCode", default: "Auto")
static let autoSelectAudioLangCode = Key<String>("AutoSelectAudioLangCode", default: "Auto")
static let appAppearance = Key<String>("appAppearance", default: AppAppearance.system.rawValue)
static let videoPlayerJumpForward = Key<Int32>("videoPlayerJumpForward", default: VideoPlayerJumpLength.thirty.rawValue)
static let videoPlayerJumpBackward = Key<Int32>("videoPlayerJumpBackward", default: VideoPlayerJumpLength.thirty.rawValue)
}

View File

@ -0,0 +1,59 @@
//
/*
* 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 UIKit
enum VideoPlayerJumpLength: Int32, CaseIterable {
case thirty = 30
case fifteen = 15
case ten = 10
// TODO - Uncomment once iOS 15 released
// case five = 5
var label: String {
return "\(self.rawValue) seconds"
}
func generateForwardImage(with font: UIFont) -> UIImage {
let config = UIImage.SymbolConfiguration(font: font)
let systemName: String
switch self {
case .thirty:
systemName = "goforward.30"
case .fifteen:
systemName = "goforward.15"
case .ten:
systemName = "goforward.10"
// case .five:
// systemName = "goforward.5"
}
return UIImage(systemName: systemName, withConfiguration: config)!
}
func generateBackwardImage(with font: UIFont) -> UIImage {
let config = UIImage.SymbolConfiguration(font: font)
let systemName: String
switch self {
case .thirty:
systemName = "gobackward.30"
case .fifteen:
systemName = "gobackward.15"
case .ten:
systemName = "gobackward.10"
// case .five:
// systemName = "gobackward.5"
}
return UIImage(systemName: systemName, withConfiguration: config)!
}
}

View File

@ -57,6 +57,7 @@ final class SettingsViewModel: ObservableObject {
var bitrates: [Bitrates] = []
var langs = [TrackLanguage]()
let appearances = AppAppearance.allCases
let videoPlayerJumpLengths = VideoPlayerJumpLength.allCases
init() {
let url = Bundle.main.url(forResource: "bitrates", withExtension: "json")!