1
0
Fork 0
mirror of https://github.com/HenkKalkwater/harbour-sailfin.git synced 2025-09-04 01:42:44 +00:00

core: Split PlaybackManager up into smaller parts

The PlaybackManager was a giant class that handled UI bindings, fetching
stream URLS, playback logic.

It now has been split up into:

- ViewModel::PlaybackManager, which handles UI interfacing and allowing
  to swap out the Model::Playback implementation on the fly.
- Model::PlaybackManager, which is an interface for what a
  PlaybackManager must do, handling queues/playlists, and controlling a
  player.
- Model::LocalPlaybackManager, which is an Model::PlaybackManager
  implementation for playing back Jellyfin media within the application.
- Model::PlaybackReporter, which reports the current playback state to
  the Jellyfin server, for keeping track of played items.
- Model::Player, which handles playing back media from an URL and
  the usual play/pause et cetera.

In a future commit, this would allow for introducing a
Model::RemoteJellyfinPlaybackManager, to control other Jellyfin
instances.
This commit is contained in:
Chris Josten 2022-01-05 21:24:52 +01:00 committed by Henk Kalkwater
parent f91e9f88e7
commit c72c10bad4
No known key found for this signature in database
GPG key ID: A69C050E9FD9FF6A
20 changed files with 1916 additions and 684 deletions

View file

@ -48,7 +48,7 @@ PanelBackground {
property bool showQueue: false
property bool _pageWasShowingNavigationIndicator
readonly property bool mediaLoading: [MediaPlayer.Loading, MediaPlayer.Buffering].indexOf(manager.mediaStatus) >= 0
readonly property bool mediaLoading: [J.MediaStatus.Loading, J.MediaStatus.Buffering].indexOf(manager.mediaStatus) >= 0
transform: Translate {id: playbackBarTranslate; y: 0}
@ -134,14 +134,24 @@ PanelBackground {
Label {
id: artists
text: {
//return manager.item.mediaType;
if (manager.item === null) return qsTr("Play some media!")
switch(manager.item.mediaType) {
case "Audio":
return manager.item.artists.join(", ")
var links = [];
var items = manager.item.artistItems;
console.log(items)
for (var i = 0; i < items.length; i++) {
links.push("<a href=\"%1\" style=\"text-decoration:none;color:%3\">%2</a>"
.arg(items[i].jellyfinId)
.arg(items[i].name)
.arg(Theme.secondaryColor)
)
}
return links.join(", ")
}
return qsTr("No audio")
}
width: Math.min(contentWidth, parent.width)
font.pixelSize: Theme.fontSizeSmall
maximumLineCount: 1
@ -151,7 +161,7 @@ PanelBackground {
onLinkActivated: {
appWindow.navigateToItem(link, "Audio", "MusicArtist", true)
}
textFormat: Text.RichText
textFormat: Text.StyledText
}
}
@ -257,7 +267,7 @@ PanelBackground {
states: [
State {
name: ""
when: manager.playbackState !== MediaPlayer.StoppedState && !isFullPage && !("__hidePlaybackBar" in pageStack.currentPage)
when: manager.playbackState !== J.PlayerState.Stopped && !isFullPage && !("__hidePlaybackBar" in pageStack.currentPage)
},
State {
name: "large"
@ -354,20 +364,6 @@ PanelBackground {
PropertyChanges {
target: artists
font.pixelSize: Theme.fontSizeMedium
text: {
var links = [];
var items = manager.item.artistItems;
console.log(items)
for (var i = 0; i < items.length; i++) {
links.push("<a href=\"%1\" style=\"text-decoration:none;color:%3\">%2</a>"
.arg(items[i].jellyfinId)
.arg(items[i].name)
.arg(Theme.secondaryColor)
)
}
return links.join(", ")
}
}
AnchorChanges {
@ -390,7 +386,7 @@ PanelBackground {
},
State {
name: "hidden"
when: ((manager.playbackState === MediaPlayer.StoppedState && !mediaLoading) || "__hidePlaybackBar" in pageStack.currentPage) && !isFullPage
when: ((manager.playbackState === J.PlayerState.Stopped && !mediaLoading) || "__hidePlaybackBar" in pageStack.currentPage) && !isFullPage
PropertyChanges {
target: playbackBarTranslate
// + small padding since the ProgressBar otherwise would stick out

View file

@ -42,6 +42,7 @@ SilicaItem {
property int subtitleTrack: 0
//FIXME: Once QTBUG-10822 is resolved, change to J.PlaybackManager
property var manager;
onManagerChanged: console.log(manager.player)
// Blackground to prevent the ambience from leaking through
Rectangle {
@ -53,6 +54,9 @@ SilicaItem {
id: videoOutput
source: manager
anchors.fill: parent
Component.onCompleted: {
console.log(manager.player)
}
}
VideoHud {
@ -71,14 +75,16 @@ SilicaItem {
Label {
readonly property string _playbackMethod: {
switch(manager.playMethod) {
case J.PlaybackManager.DirectPlay:
return"Direct Play"
case J.PlaybackManager.Transcoding:
case J.PlayMethod.EnumNotSet:
return "Enum not set"
case J.PlayMethod.DirectPlay:
return "Direct Play"
case J.PlayMethod.Transcode:
return "Transcoding"
case J.PlaybackManager.DirectStream:
case J.PlayMethod.DirectStream:
return "Direct Stream"
default:
return "Unknown playback method"
return "Unknown playback method '%1'".arg(manager.playMethod)
}
}
anchors.fill: parent
@ -86,6 +92,7 @@ SilicaItem {
text: item.jellyfinId + "\n" + appWindow.playbackManager.streamUrl + "\n"
+ "Playback method: " + _playbackMethod + "\n"
+ "Media status: " + manager.mediaStatus + "\n"
+ "Playback state: " + manager.playbackState + "\n"
// + player.bufferProgress + "\n"
// + player.metaData.videoCodec + "@" + player.metaData.videoFrameRate + "(" + player.metaData.videoBitRate + ")" + "\n"
// + player.metaData.audioCodec + "(" + player.metaData.audioBitRate + ")" + "\n"

View file

@ -79,16 +79,17 @@ Item {
id: busyIndicator
anchors.centerIn: parent
size: BusyIndicatorSize.Medium
running: [MediaPlayer.Loading, MediaPlayer.Stalled].indexOf(manager.mediaStatus) >= 0
running: [J.MediaStatus.Loading, J.MediaStatus.Stalled].indexOf(manager.mediaStatus) >= 0
}
IconButton {
id: playPause
enabled: !hidden
anchors.centerIn: parent
icon.source: manager.playbackState === MediaPlayer.PausedState ? "image://theme/icon-l-play" : "image://theme/icon-l-pause"
icon.source: manager.playbackState === J.PlayerState.Paused ? "image://theme/icon-l-play" : "image://theme/icon-l-pause"
onClicked: {
if (manager.playbackState === MediaPlayer.PlayingState) {
console.log(manager.playbackState)
if (manager.playbackState === J.PlayerState.Playing) {
manager.pause()
} else {
manager.play()
@ -102,7 +103,7 @@ Item {
anchors.bottom: parent.bottom
width: parent.width
height: progress.height
visible: [MediaPlayer.Unavailable, MediaPlayer.Loading, MediaPlayer.NoMedia].indexOf(manager.mediaStatus) == -1
visible: [J.MediaStatus.Unavailable, J.MediaStatus.Loading, J.MediaStatus.NoMedia].indexOf(manager.mediaStatus) == -1
gradient: Gradient {
GradientStop { position: 0.0; color: Theme.rgba(palette.overlayBackgroundColor, 0.15); }
@ -151,11 +152,11 @@ Item {
onMediaStatusChanged: {
console.log("New mediaPlayer status: " + manager.mediaStatus)
switch(manager.mediaStatus) {
case MediaPlayer.Loaded:
case MediaPlayer.Buffering:
case J.MediaStatus.Loaded:
case J.MediaStatus.Buffering:
show(false)
break;
case MediaPlayer.Buffered:
case J.MediaStatus.Buffered:
hide(false)
break;
}

View file

@ -1,6 +1,6 @@
/*
Sailfin: a Jellyfin client written using Qt
Copyright (C) 2020 Chris Josten
Copyright (C) 2020-2022 Chris Josten
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@ -114,7 +114,6 @@ ApplicationWindow {
id: _playbackManager
apiClient: appWindow.apiClient
audioIndex: 0
autoOpen: true
}
Connections {