persist subtitle state across items

This commit is contained in:
Ethan Pippin 2021-12-30 00:54:21 -07:00
parent bc542dad8d
commit 4219ecc8dc
2 changed files with 57 additions and 22 deletions

View File

@ -259,9 +259,6 @@ extension VLCPlayerViewController {
newViewModel.sliderPercentage = startPercentage / 100
}
didSelectSubtitleStream(index: newViewModel.selectedSubtitleStreamIndex)
didSelectAudioStream(index: newViewModel.selectedAudioStreamIndex)
viewModel = newViewModel
}
@ -374,6 +371,8 @@ extension VLCPlayerViewController {
// MARK: VLCMediaPlayerDelegate
extension VLCPlayerViewController: VLCMediaPlayerDelegate {
// MARK: mediaPlayerStateChanged
func mediaPlayerStateChanged(_ aNotification: Notification!) {
self.viewModel.playerState = vlcMediaPlayer.state
@ -383,6 +382,7 @@ extension VLCPlayerViewController: VLCMediaPlayerDelegate {
}
}
// MARK: mediaPlayerTimeChanged
func mediaPlayerTimeChanged(_ aNotification: Notification!) {
guard !viewModel.sliderIsScrubbing else {
@ -398,6 +398,12 @@ extension VLCPlayerViewController: VLCMediaPlayerDelegate {
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
// Send progress report every 5 seconds
@ -414,15 +420,22 @@ extension VLCPlayerViewController: PlayerOverlayDelegate {
func didSelectAudioStream(index: Int) {
vlcMediaPlayer.currentAudioTrackIndex = Int32(index)
viewModel.sendProgressReport()
lastProgressReportTicks = currentPlayerTicks
}
func didSelectSubtitleStream(index: Int) {
if viewModel.subtitlesEnabled {
vlcMediaPlayer.currentVideoSubTitleIndex = Int32(index)
if index != -1 {
// set in case weren't shown
viewModel.subtitlesEnabled = true
} else {
vlcMediaPlayer.currentVideoSubTitleIndex = -1
}
viewModel.sendProgressReport()
lastProgressReportTicks = currentPlayerTicks
}
func didSelectClose() {

View File

@ -23,7 +23,14 @@ final class VideoPlayerViewModel: ViewModel {
@Published var playerState: VLCMediaPlayerState
@Published var shouldShowGoogleCast: 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 rightLabelText: String = "--:--"
@Published var playbackSpeed: PlaybackSpeed = .one
@ -237,11 +244,15 @@ extension VideoPlayerViewModel {
}
private func matchSubtitleStream(with masterViewModel: VideoPlayerViewModel) {
guard let currentSubtitleStream = masterViewModel.subtitleStreams.first(where: { $0.index == masterViewModel.selectedSubtitleStreamIndex }) else { return }
guard let matchingSubtitleStream = self.subtitleStreams.first(where: { mediaStreamAboutEqual($0, currentSubtitleStream) }) else { return }
if !masterViewModel.subtitlesEnabled {
matchSubtitlesEnabled(with: masterViewModel)
}
self.subtitlesEnabled = masterViewModel.subtitlesEnabled
self.selectedSubtitleStreamIndex = matchingSubtitleStream.index ?? -1
guard let masterSubtitleStream = masterViewModel.subtitleStreams.first(where: { $0.index == masterViewModel.selectedSubtitleStreamIndex }),
let matchingSubtitleStream = self.subtitleStreams.first(where: { mediaStreamAboutEqual($0, masterSubtitleStream) }),
let matchingSubtitleStreamIndex = matchingSubtitleStream.index else { return }
self.selectedSubtitleStreamIndex = matchingSubtitleStreamIndex
}
private func matchAudioStream(with masterViewModel: VideoPlayerViewModel) {
@ -251,12 +262,16 @@ extension VideoPlayerViewModel {
self.selectedAudioStreamIndex = matchingAudioStream.index ?? -1
}
private func matchSubtitlesEnabled(with masterViewModel: VideoPlayerViewModel) {
self.subtitlesEnabled = masterViewModel.subtitlesEnabled
}
private func mediaStreamAboutEqual(_ lhs: MediaStream, _ rhs: MediaStream) -> Bool {
return lhs.displayTitle == rhs.displayTitle && lhs.language == rhs.language
}
}
// MARK: Reports
// MARK: Updates
extension VideoPlayerViewModel {
@ -265,13 +280,15 @@ extension VideoPlayerViewModel {
self.startTimeTicks = Int64(Date().timeIntervalSince1970) * 10_000_000
let subtitleStreamIndex = subtitlesEnabled ? selectedSubtitleStreamIndex : nil
let startInfo = PlaybackStartInfo(canSeek: true,
item: item,
itemId: item.id,
sessionId: response.playSessionId,
mediaSourceId: item.id,
audioStreamIndex: audioStreams.first(where: { $0.index! == response.mediaSources?.first?.defaultAudioStreamIndex! })?.index,
subtitleStreamIndex: subtitleStreams.first(where: { $0.index! == response.mediaSources?.first?.defaultSubtitleStreamIndex ?? -1 })?.index,
audioStreamIndex: selectedAudioStreamIndex,
subtitleStreamIndex: subtitleStreamIndex,
isPaused: false,
isMuted: false,
positionTicks: item.userData?.playbackPositionTicks,
@ -298,13 +315,16 @@ extension VideoPlayerViewModel {
// MARK: sendPauseReport
func sendPauseReport(paused: Bool) {
let startInfo = PlaybackStartInfo(canSeek: true,
let subtitleStreamIndex = subtitlesEnabled ? selectedSubtitleStreamIndex : nil
let pauseInfo = PlaybackStartInfo(canSeek: true,
item: item,
itemId: item.id,
sessionId: response.playSessionId,
mediaSourceId: item.id,
audioStreamIndex: audioStreams.first(where: { $0.index! == response.mediaSources?.first?.defaultAudioStreamIndex! })?.index,
subtitleStreamIndex: subtitleStreams.first(where: { $0.index! == response.mediaSources?.first?.defaultSubtitleStreamIndex ?? -1 })?.index,
audioStreamIndex: selectedAudioStreamIndex,
subtitleStreamIndex: subtitleStreamIndex,
isPaused: paused,
isMuted: false,
positionTicks: currentSecondTicks,
@ -320,7 +340,7 @@ extension VideoPlayerViewModel {
playlistItemId: "playlistItem0"
)
PlaystateAPI.reportPlaybackStart(playbackStartInfo: startInfo)
PlaystateAPI.reportPlaybackStart(playbackStartInfo: pauseInfo)
.sink { completion in
self.handleAPIRequestError(completion: completion)
} receiveValue: { _ in
@ -332,13 +352,15 @@ extension VideoPlayerViewModel {
// MARK: sendProgressReport
func sendProgressReport() {
let subtitleStreamIndex = subtitlesEnabled ? selectedSubtitleStreamIndex : nil
let progressInfo = PlaybackProgressInfo(canSeek: true,
item: item,
itemId: item.id,
sessionId: response.playSessionId,
mediaSourceId: item.id,
audioStreamIndex: audioStreams.first(where: { $0.index! == response.mediaSources?.first?.defaultAudioStreamIndex! })?.index,
subtitleStreamIndex: subtitleStreams.first(where: { $0.index! == response.mediaSources?.first?.defaultSubtitleStreamIndex ?? -1 })?.index,
audioStreamIndex: selectedAudioStreamIndex,
subtitleStreamIndex: subtitleStreamIndex,
isPaused: false,
isMuted: false,
positionTicks: currentSecondTicks,