persist subtitle state across items
This commit is contained in:
parent
bc542dad8d
commit
4219ecc8dc
|
@ -259,9 +259,6 @@ extension VLCPlayerViewController {
|
||||||
newViewModel.sliderPercentage = startPercentage / 100
|
newViewModel.sliderPercentage = startPercentage / 100
|
||||||
}
|
}
|
||||||
|
|
||||||
didSelectSubtitleStream(index: newViewModel.selectedSubtitleStreamIndex)
|
|
||||||
didSelectAudioStream(index: newViewModel.selectedAudioStreamIndex)
|
|
||||||
|
|
||||||
viewModel = newViewModel
|
viewModel = newViewModel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,6 +371,8 @@ extension VLCPlayerViewController {
|
||||||
// MARK: VLCMediaPlayerDelegate
|
// MARK: VLCMediaPlayerDelegate
|
||||||
extension VLCPlayerViewController: VLCMediaPlayerDelegate {
|
extension VLCPlayerViewController: VLCMediaPlayerDelegate {
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: mediaPlayerStateChanged
|
||||||
func mediaPlayerStateChanged(_ aNotification: Notification!) {
|
func mediaPlayerStateChanged(_ aNotification: Notification!) {
|
||||||
|
|
||||||
self.viewModel.playerState = vlcMediaPlayer.state
|
self.viewModel.playerState = vlcMediaPlayer.state
|
||||||
|
@ -383,6 +382,7 @@ extension VLCPlayerViewController: VLCMediaPlayerDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: mediaPlayerTimeChanged
|
||||||
func mediaPlayerTimeChanged(_ aNotification: Notification!) {
|
func mediaPlayerTimeChanged(_ aNotification: Notification!) {
|
||||||
|
|
||||||
guard !viewModel.sliderIsScrubbing else {
|
guard !viewModel.sliderIsScrubbing else {
|
||||||
|
@ -398,6 +398,12 @@ extension VLCPlayerViewController: VLCMediaPlayerDelegate {
|
||||||
viewModel.playerState = VLCMediaPlayerState.playing
|
viewModel.playerState = VLCMediaPlayerState.playing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If needing to fix subtitle streams during playback
|
||||||
|
if vlcMediaPlayer.currentVideoSubTitleIndex != viewModel.selectedSubtitleStreamIndex && viewModel.subtitlesEnabled {
|
||||||
|
didSelectSubtitleStream(index: viewModel.selectedSubtitleStreamIndex)
|
||||||
|
didSelectAudioStream(index: viewModel.selectedAudioStreamIndex)
|
||||||
|
}
|
||||||
|
|
||||||
lastPlayerTicks = currentPlayerTicks
|
lastPlayerTicks = currentPlayerTicks
|
||||||
|
|
||||||
// Send progress report every 5 seconds
|
// Send progress report every 5 seconds
|
||||||
|
@ -414,15 +420,22 @@ extension VLCPlayerViewController: PlayerOverlayDelegate {
|
||||||
|
|
||||||
func didSelectAudioStream(index: Int) {
|
func didSelectAudioStream(index: Int) {
|
||||||
vlcMediaPlayer.currentAudioTrackIndex = Int32(index)
|
vlcMediaPlayer.currentAudioTrackIndex = Int32(index)
|
||||||
|
|
||||||
|
viewModel.sendProgressReport()
|
||||||
|
|
||||||
|
lastProgressReportTicks = currentPlayerTicks
|
||||||
}
|
}
|
||||||
|
|
||||||
func didSelectSubtitleStream(index: Int) {
|
func didSelectSubtitleStream(index: Int) {
|
||||||
vlcMediaPlayer.currentVideoSubTitleIndex = Int32(index)
|
if viewModel.subtitlesEnabled {
|
||||||
|
vlcMediaPlayer.currentVideoSubTitleIndex = Int32(index)
|
||||||
if index != -1 {
|
} else {
|
||||||
// set in case weren't shown
|
vlcMediaPlayer.currentVideoSubTitleIndex = -1
|
||||||
viewModel.subtitlesEnabled = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewModel.sendProgressReport()
|
||||||
|
|
||||||
|
lastProgressReportTicks = currentPlayerTicks
|
||||||
}
|
}
|
||||||
|
|
||||||
func didSelectClose() {
|
func didSelectClose() {
|
||||||
|
|
|
@ -23,7 +23,14 @@ final class VideoPlayerViewModel: ViewModel {
|
||||||
@Published var playerState: VLCMediaPlayerState
|
@Published var playerState: VLCMediaPlayerState
|
||||||
@Published var shouldShowGoogleCast: Bool
|
@Published var shouldShowGoogleCast: Bool
|
||||||
@Published var shouldShowAirplay: Bool
|
@Published var shouldShowAirplay: Bool
|
||||||
@Published var subtitlesEnabled: Bool
|
@Published var subtitlesEnabled: Bool {
|
||||||
|
didSet {
|
||||||
|
if subtitlesEnabled != oldValue {
|
||||||
|
previousItemVideoPlayerViewModel?.matchSubtitlesEnabled(with: self)
|
||||||
|
nextItemVideoPlayerViewModel?.matchSubtitlesEnabled(with: self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@Published var leftLabelText: String = "--:--"
|
@Published var leftLabelText: String = "--:--"
|
||||||
@Published var rightLabelText: String = "--:--"
|
@Published var rightLabelText: String = "--:--"
|
||||||
@Published var playbackSpeed: PlaybackSpeed = .one
|
@Published var playbackSpeed: PlaybackSpeed = .one
|
||||||
|
@ -237,11 +244,15 @@ extension VideoPlayerViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func matchSubtitleStream(with masterViewModel: VideoPlayerViewModel) {
|
private func matchSubtitleStream(with masterViewModel: VideoPlayerViewModel) {
|
||||||
guard let currentSubtitleStream = masterViewModel.subtitleStreams.first(where: { $0.index == masterViewModel.selectedSubtitleStreamIndex }) else { return }
|
if !masterViewModel.subtitlesEnabled {
|
||||||
guard let matchingSubtitleStream = self.subtitleStreams.first(where: { mediaStreamAboutEqual($0, currentSubtitleStream) }) else { return }
|
matchSubtitlesEnabled(with: masterViewModel)
|
||||||
|
}
|
||||||
|
|
||||||
self.subtitlesEnabled = masterViewModel.subtitlesEnabled
|
guard let masterSubtitleStream = masterViewModel.subtitleStreams.first(where: { $0.index == masterViewModel.selectedSubtitleStreamIndex }),
|
||||||
self.selectedSubtitleStreamIndex = matchingSubtitleStream.index ?? -1
|
let matchingSubtitleStream = self.subtitleStreams.first(where: { mediaStreamAboutEqual($0, masterSubtitleStream) }),
|
||||||
|
let matchingSubtitleStreamIndex = matchingSubtitleStream.index else { return }
|
||||||
|
|
||||||
|
self.selectedSubtitleStreamIndex = matchingSubtitleStreamIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
private func matchAudioStream(with masterViewModel: VideoPlayerViewModel) {
|
private func matchAudioStream(with masterViewModel: VideoPlayerViewModel) {
|
||||||
|
@ -251,12 +262,16 @@ extension VideoPlayerViewModel {
|
||||||
self.selectedAudioStreamIndex = matchingAudioStream.index ?? -1
|
self.selectedAudioStreamIndex = matchingAudioStream.index ?? -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func matchSubtitlesEnabled(with masterViewModel: VideoPlayerViewModel) {
|
||||||
|
self.subtitlesEnabled = masterViewModel.subtitlesEnabled
|
||||||
|
}
|
||||||
|
|
||||||
private func mediaStreamAboutEqual(_ lhs: MediaStream, _ rhs: MediaStream) -> Bool {
|
private func mediaStreamAboutEqual(_ lhs: MediaStream, _ rhs: MediaStream) -> Bool {
|
||||||
return lhs.displayTitle == rhs.displayTitle && lhs.language == rhs.language
|
return lhs.displayTitle == rhs.displayTitle && lhs.language == rhs.language
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Reports
|
// MARK: Updates
|
||||||
extension VideoPlayerViewModel {
|
extension VideoPlayerViewModel {
|
||||||
|
|
||||||
|
|
||||||
|
@ -265,13 +280,15 @@ extension VideoPlayerViewModel {
|
||||||
|
|
||||||
self.startTimeTicks = Int64(Date().timeIntervalSince1970) * 10_000_000
|
self.startTimeTicks = Int64(Date().timeIntervalSince1970) * 10_000_000
|
||||||
|
|
||||||
|
let subtitleStreamIndex = subtitlesEnabled ? selectedSubtitleStreamIndex : nil
|
||||||
|
|
||||||
let startInfo = PlaybackStartInfo(canSeek: true,
|
let startInfo = PlaybackStartInfo(canSeek: true,
|
||||||
item: item,
|
item: item,
|
||||||
itemId: item.id,
|
itemId: item.id,
|
||||||
sessionId: response.playSessionId,
|
sessionId: response.playSessionId,
|
||||||
mediaSourceId: item.id,
|
mediaSourceId: item.id,
|
||||||
audioStreamIndex: audioStreams.first(where: { $0.index! == response.mediaSources?.first?.defaultAudioStreamIndex! })?.index,
|
audioStreamIndex: selectedAudioStreamIndex,
|
||||||
subtitleStreamIndex: subtitleStreams.first(where: { $0.index! == response.mediaSources?.first?.defaultSubtitleStreamIndex ?? -1 })?.index,
|
subtitleStreamIndex: subtitleStreamIndex,
|
||||||
isPaused: false,
|
isPaused: false,
|
||||||
isMuted: false,
|
isMuted: false,
|
||||||
positionTicks: item.userData?.playbackPositionTicks,
|
positionTicks: item.userData?.playbackPositionTicks,
|
||||||
|
@ -298,13 +315,16 @@ extension VideoPlayerViewModel {
|
||||||
|
|
||||||
// MARK: sendPauseReport
|
// MARK: sendPauseReport
|
||||||
func sendPauseReport(paused: Bool) {
|
func sendPauseReport(paused: Bool) {
|
||||||
let startInfo = PlaybackStartInfo(canSeek: true,
|
|
||||||
|
let subtitleStreamIndex = subtitlesEnabled ? selectedSubtitleStreamIndex : nil
|
||||||
|
|
||||||
|
let pauseInfo = PlaybackStartInfo(canSeek: true,
|
||||||
item: item,
|
item: item,
|
||||||
itemId: item.id,
|
itemId: item.id,
|
||||||
sessionId: response.playSessionId,
|
sessionId: response.playSessionId,
|
||||||
mediaSourceId: item.id,
|
mediaSourceId: item.id,
|
||||||
audioStreamIndex: audioStreams.first(where: { $0.index! == response.mediaSources?.first?.defaultAudioStreamIndex! })?.index,
|
audioStreamIndex: selectedAudioStreamIndex,
|
||||||
subtitleStreamIndex: subtitleStreams.first(where: { $0.index! == response.mediaSources?.first?.defaultSubtitleStreamIndex ?? -1 })?.index,
|
subtitleStreamIndex: subtitleStreamIndex,
|
||||||
isPaused: paused,
|
isPaused: paused,
|
||||||
isMuted: false,
|
isMuted: false,
|
||||||
positionTicks: currentSecondTicks,
|
positionTicks: currentSecondTicks,
|
||||||
|
@ -320,7 +340,7 @@ extension VideoPlayerViewModel {
|
||||||
playlistItemId: "playlistItem0"
|
playlistItemId: "playlistItem0"
|
||||||
)
|
)
|
||||||
|
|
||||||
PlaystateAPI.reportPlaybackStart(playbackStartInfo: startInfo)
|
PlaystateAPI.reportPlaybackStart(playbackStartInfo: pauseInfo)
|
||||||
.sink { completion in
|
.sink { completion in
|
||||||
self.handleAPIRequestError(completion: completion)
|
self.handleAPIRequestError(completion: completion)
|
||||||
} receiveValue: { _ in
|
} receiveValue: { _ in
|
||||||
|
@ -332,13 +352,15 @@ extension VideoPlayerViewModel {
|
||||||
// MARK: sendProgressReport
|
// MARK: sendProgressReport
|
||||||
func sendProgressReport() {
|
func sendProgressReport() {
|
||||||
|
|
||||||
|
let subtitleStreamIndex = subtitlesEnabled ? selectedSubtitleStreamIndex : nil
|
||||||
|
|
||||||
let progressInfo = PlaybackProgressInfo(canSeek: true,
|
let progressInfo = PlaybackProgressInfo(canSeek: true,
|
||||||
item: item,
|
item: item,
|
||||||
itemId: item.id,
|
itemId: item.id,
|
||||||
sessionId: response.playSessionId,
|
sessionId: response.playSessionId,
|
||||||
mediaSourceId: item.id,
|
mediaSourceId: item.id,
|
||||||
audioStreamIndex: audioStreams.first(where: { $0.index! == response.mediaSources?.first?.defaultAudioStreamIndex! })?.index,
|
audioStreamIndex: selectedAudioStreamIndex,
|
||||||
subtitleStreamIndex: subtitleStreams.first(where: { $0.index! == response.mediaSources?.first?.defaultSubtitleStreamIndex ?? -1 })?.index,
|
subtitleStreamIndex: subtitleStreamIndex,
|
||||||
isPaused: false,
|
isPaused: false,
|
||||||
isMuted: false,
|
isMuted: false,
|
||||||
positionTicks: currentSecondTicks,
|
positionTicks: currentSecondTicks,
|
||||||
|
|
Loading…
Reference in New Issue