mirror of
https://github.com/yattee/yattee.git
synced 2025-08-06 10:44:06 +00:00
Initial PeerTube Support
This commit is contained in:
@@ -65,6 +65,7 @@ final class MPVClient: ObservableObject {
|
||||
checkError(mpv_set_option_string(mpv, "keep-open", "yes"))
|
||||
checkError(mpv_set_option_string(mpv, "hwdec", machine == "x86_64" ? "no" : "auto-safe"))
|
||||
checkError(mpv_set_option_string(mpv, "vo", "libmpv"))
|
||||
checkError(mpv_set_option_string(mpv, "demuxer-lavf-analyzeduration", "1"))
|
||||
|
||||
checkError(mpv_initialize(mpv))
|
||||
|
||||
@@ -134,8 +135,9 @@ final class MPVClient: ObservableObject {
|
||||
var args = [url.absoluteString]
|
||||
var options = [String]()
|
||||
|
||||
if let time {
|
||||
args.append("replace")
|
||||
args.append("replace")
|
||||
|
||||
if let time, time.seconds > 0 {
|
||||
options.append("start=\(Int(time.seconds))")
|
||||
}
|
||||
|
||||
@@ -148,9 +150,11 @@ final class MPVClient: ObservableObject {
|
||||
}
|
||||
|
||||
if forceSeekable {
|
||||
options.append("force-seekable=yes")
|
||||
// options.append("stream-lavf-o=seekable=0")
|
||||
}
|
||||
|
||||
options.append("stream-lavf-o=seekable=0")
|
||||
|
||||
if !options.isEmpty {
|
||||
args.append(options.joined(separator: ","))
|
||||
}
|
||||
|
@@ -99,7 +99,7 @@ final class PlayerModel: ObservableObject {
|
||||
@Published var queueItemBeingLoaded: PlayerQueueItem?
|
||||
@Published var queueItemsToLoad = [PlayerQueueItem]()
|
||||
@Published var historyItemBeingLoaded: Video.ID?
|
||||
@Published var historyItemsToLoad = [Video.ID]()
|
||||
@Published var historyItemsToLoad = [Watch]()
|
||||
|
||||
@Published var preservedTime: CMTime?
|
||||
|
||||
@@ -125,6 +125,7 @@ final class PlayerModel: ObservableObject {
|
||||
@Default(.rotateToPortraitOnExitFullScreen) private var rotateToPortraitOnExitFullScreen
|
||||
#endif
|
||||
|
||||
var accounts: AccountsModel { .shared }
|
||||
var comments: CommentsModel { .shared }
|
||||
var controls: PlayerControlsModel { .shared }
|
||||
var playerTime: PlayerTimeModel { .shared }
|
||||
@@ -152,6 +153,7 @@ final class PlayerModel: ObservableObject {
|
||||
}
|
||||
}}
|
||||
|
||||
@Default(.saveHistory) var saveHistory
|
||||
@Default(.saveLastPlayed) var saveLastPlayed
|
||||
@Default(.lastPlayed) var lastPlayed
|
||||
@Default(.qualityProfiles) var qualityProfiles
|
||||
@@ -709,7 +711,7 @@ final class PlayerModel: ObservableObject {
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 3) { [weak self] in
|
||||
guard let self else { return }
|
||||
self.playerAPI.loadDetails(item, completionHandler: { newItem in
|
||||
self.playerAPI(item.video).loadDetails(item, completionHandler: { newItem in
|
||||
guard newItem.videoID == self.autoplayItem?.videoID else { return }
|
||||
self.autoplayItem = newItem
|
||||
self.updateRemoteCommandCenter()
|
||||
|
@@ -83,11 +83,21 @@ extension PlayerModel {
|
||||
}
|
||||
|
||||
var playerInstance: Instance? {
|
||||
InstancesModel.shared.forPlayer ?? AccountsModel.shared.current?.instance ?? InstancesModel.shared.all.first
|
||||
InstancesModel.shared.forPlayer ?? accounts.current?.instance ?? InstancesModel.shared.all.first
|
||||
}
|
||||
|
||||
var playerAPI: VideosAPI {
|
||||
playerInstance?.anonymous ?? AccountsModel.shared.api
|
||||
func playerAPI(_ video: Video) -> VideosAPI! {
|
||||
guard let url = video.instanceURL else { return nil }
|
||||
switch video.app {
|
||||
case .local:
|
||||
return nil
|
||||
case .peerTube:
|
||||
return PeerTubeAPI.withAnonymousAccountForInstanceURL(url)
|
||||
case .invidious:
|
||||
return InvidiousAPI.withAnonymousAccountForInstanceURL(url)
|
||||
case .piped:
|
||||
return PipedAPI.withAnonymousAccountForInstanceURL(url)
|
||||
}
|
||||
}
|
||||
|
||||
var qualityProfile: QualityProfile? {
|
||||
@@ -155,7 +165,7 @@ extension PlayerModel {
|
||||
currentItem.playbackTime = time
|
||||
|
||||
let playTime = currentItem.shouldRestartPlaying ? CMTime.zero : time
|
||||
playerAPI.loadDetails(currentItem, failureHandler: { self.videoLoadFailureHandler($0, video: self.currentItem.video) }) { newItem in
|
||||
playerAPI(newItem.video).loadDetails(currentItem, failureHandler: { self.videoLoadFailureHandler($0, video: self.currentItem.video) }) { newItem in
|
||||
self.playItem(newItem, at: playTime)
|
||||
}
|
||||
}
|
||||
@@ -198,7 +208,7 @@ extension PlayerModel {
|
||||
}
|
||||
|
||||
if loadDetails {
|
||||
playerAPI.loadDetails(item, failureHandler: { self.videoLoadFailureHandler($0, video: video) }) { [weak self] newItem in
|
||||
playerAPI(item.video).loadDetails(item, failureHandler: { self.videoLoadFailureHandler($0, video: video) }) { [weak self] newItem in
|
||||
guard let self else { return }
|
||||
videoDetailsLoadHandler(newItem.video, newItem)
|
||||
|
||||
@@ -269,7 +279,7 @@ extension PlayerModel {
|
||||
}
|
||||
|
||||
func loadQueueVideoDetails(_ item: PlayerQueueItem) {
|
||||
guard !AccountsModel.shared.current.isNil, !item.hasDetailsLoaded else { return }
|
||||
guard !accounts.current.isNil, !item.hasDetailsLoaded else { return }
|
||||
|
||||
let videoID = item.video?.videoID ?? item.videoID
|
||||
|
||||
@@ -282,7 +292,7 @@ extension PlayerModel {
|
||||
return
|
||||
}
|
||||
|
||||
playerAPI.loadDetails(item, completionHandler: { [weak self] newItem in
|
||||
playerAPI(item.video).loadDetails(item, completionHandler: { [weak self] newItem in
|
||||
guard let self else { return }
|
||||
|
||||
self.queue.filter { $0.videoID == item.videoID }.forEach { item in
|
||||
|
@@ -21,7 +21,7 @@ extension PlayerModel {
|
||||
guard let playerInstance else { return }
|
||||
|
||||
logger.info("loading streams from \(playerInstance.description)")
|
||||
fetchStreams(playerAPI.video(video.videoID), instance: playerInstance, video: video)
|
||||
fetchStreams(playerAPI(video).video(video.videoID), instance: playerInstance, video: video)
|
||||
}
|
||||
|
||||
private func fetchStreams(
|
||||
|
Reference in New Issue
Block a user