on xenial help sign in
Make sure we emit sounds when taking a screenshot even after media-hub
a978942Alfonso Sanchez-Beato
plugins/Dash/DashAudioPlayer.qml+45−21
@@ -20,16 +20,22 @@ import QtMultimedia 5.6
20import Dash 0.1
20import Dash 0.1
21
21
22QtObject {
22QtObject {
23+ id: root
23− readonly property real progress: audio.position / audio.duration
24+ readonly property real progress: priv.audio ? priv.audio.position / priv.audio.duration : 0.0
24− readonly property bool playing: audio.playbackState === Audio.PlayingState
25+ readonly property bool playing: priv.audio ? priv.audio.playbackState === Audio.PlayingState : false
25− readonly property bool paused: audio.playbackState === Audio.PausedState
26+ readonly property bool paused: priv.audio ? priv.audio.playbackState === Audio.PausedState : false
26− readonly property bool stopped: audio.playbackState === Audio.StoppedState
27+ readonly property bool stopped: priv.audio ? priv.audio.playbackState === Audio.StoppedState : true
27− readonly property alias position: audio.position
28+ readonly property int position: priv.audio ? priv.audio.position : 0
28− readonly property url currentSource: audio.playlist.currentItemSource
29+ readonly property url currentSource: priv.audio ? priv.audio.playlist.currentItemSource : ""
30+ readonly property Playlist playlist: priv.audio ? priv.audio.playlist : null
29
31
30 function playSource(newSource, newPlaylist) {
32 function playSource(newSource, newPlaylist) {
33+ if (!priv.audio) {
34+ console.info("DashAudioPlayer: creating player");
35+ priv.audio = priv.audioComponent.createObject(root);
36+ }
31 stop();
37 stop();
32− audio.playlist.clear();
38+ priv.audio.playlist.clear();
33 if (newPlaylist) {
39 if (newPlaylist) {
34 // Look for newSource in newPlaylist
40 // Look for newSource in newPlaylist
35 var sourceIndex = -1;
41 var sourceIndex = -1;
@@ -48,35 +54,53 @@ QtObject {
48 for (var i in newPlaylist) {
54 for (var i in newPlaylist) {
49 urls.push(newPlaylist[i]);
55 urls.push(newPlaylist[i]);
50 }
56 }
51− audio.playlist.addItems(urls);
57+ priv.audio.playlist.addItems(urls);
52− audio.playlist.currentIndex = sourceIndex;
58+ priv.audio.playlist.currentIndex = sourceIndex;
53 } else {
59 } else {
54− audio.playlist.addItem(newSource);
60+ priv.audio.playlist.addItem(newSource);
55− audio.playlist.currentIndex = 0;
61+ priv.audio.playlist.currentIndex = 0;
56 }
62 }
57 play();
63 play();
58 }
64 }
59
65
60 function stop() {
66 function stop() {
67+ if (priv.audio) {
61− audio.stop();
68+ priv.audio.stop();
69+ }
62 }
70 }
63
71
64 function play() {
72 function play() {
73+ if (priv.audio) {
65− audio.play();
74+ priv.audio.play();
75+ }
66 }
76 }
67
77
68 function pause() {
78 function pause() {
79+ if (priv.audio) {
69− audio.pause();
80+ priv.audio.pause();
81+ }
70 }
82 }
71
83
72− property QtObject audio: Audio {
84+ property QtObject priv: QtObject {
73− id: audio
85+ id: priv
74− objectName: "audio"
86+ property Audio audio: null
87+ property Component audioComponent: Component {
88+ Audio {
75− playlist: Playlist {
89+ playlist: Playlist {
76− objectName: "playlist"
90+ objectName: "playlist"
91+ }
92+ /* Remove player in case of error so it gets recreated next time
93+ * we need it. Happens if backend media player restarted, for
94+ * instance. qtmultimedia should probably handle this
95+ * transparently (LP: #1616425).
96+ */
97+ onError: {
98+ console.warn("DashAudioPlayer: error event (" +
99+ priv.audio.errorString + "), destroying");
100+ priv.audio.destroy();
101+ }
102+ }
77 }
103 }
78−
79− onErrorStringChanged: console.warn("Dash Audio player error:", errorString)
80 }
104 }
81
105
82 function lengthToString(s) {
106 function lengthToString(s) {
qml/Components/NotificationAudio.qml+20−3
@@ -23,6 +23,10 @@ Item {
23 readonly property var playbackState: priv.audio ? priv.audio.playbackState : 0
23 readonly property var playbackState: priv.audio ? priv.audio.playbackState : 0
24
24
25 function play() {
25 function play() {
26+ if (!priv.audio) {
27+ console.info("NotificationAudio: creating player");
28+ priv.audio = priv.audioComponent.createObject(root);
29+ }
26 if (priv.audio) {
30 if (priv.audio) {
27 priv.audio.play();
31 priv.audio.play();
28 }
32 }
@@ -35,9 +39,22 @@ Item {
35
39
36 QtObject {
40 QtObject {
37 id: priv
41 id: priv
38− property var audio: Audio {
42+ property Audio audio: null
43+ property Component audioComponent: Component {
44+ Audio {
39− source: root.source
45+ source: root.source
40− audioRole: MediaPlayer.NotificationRole
46+ audioRole: MediaPlayer.NotificationRole
47+ /* Remove player in case of error so it gets recreated next time
48+ * we need it. Happens if backend media player restarted, for
49+ * instance. qtmultimedia should probably handle this
50+ * transparently (LP: #1616425).
51+ */
52+ onError: {
53+ console.warn("NotificationAudio: error event (" +
54+ priv.audio.errorString + "), destroying");
55+ priv.audio.destroy();
56+ }
57+ }
41 }
58 }
42 }
59 }
43}
60}
tests/qmltests/Dash/Previews/tst_PreviewAudioPlayback.qml+8−10
@@ -127,8 +127,6 @@ Rectangle {
127 var track1PlayButton = findChild(track1Item, "playButton");
127 var track1PlayButton = findChild(track1Item, "playButton");
128 var track2PlayButton = findChild(track2Item, "playButton");
128 var track2PlayButton = findChild(track2Item, "playButton");
129
129
130− var audio = DashAudioPlayer.audio;
131−
132 // All progress bars must be hidden in the beginning
130 // All progress bars must be hidden in the beginning
133 compare(track0ProgressBar.visible, false);
131 compare(track0ProgressBar.visible, false);
134 compare(track1ProgressBar.visible, false);
132 compare(track1ProgressBar.visible, false);
@@ -137,7 +135,7 @@ Rectangle {
137 // Playing track 0 should make progress bar 0 visible
135 // Playing track 0 should make progress bar 0 visible
138 mouseClick(track0PlayButton);
136 mouseClick(track0PlayButton);
139
137
140− tryCompare(audio, "playbackState", Audio.PlayingState);
138+ compare(DashAudioPlayer.playing, true);
141 checkPlayerSource(0);
139 checkPlayerSource(0);
142
140
143 tryCompare(track0ProgressBar, "visible", true);
141 tryCompare(track0ProgressBar, "visible", true);
@@ -146,25 +144,25 @@ Rectangle {
146
144
147 // Clicking the button again should pause it. The progress bar should stay visible
145 // Clicking the button again should pause it. The progress bar should stay visible
148 mouseClick(track0PlayButton);
146 mouseClick(track0PlayButton);
149− tryCompare(audio, "playbackState", Audio.PausedState);
147+ compare(DashAudioPlayer.paused, true);
150 checkPlayerSource(0);
148 checkPlayerSource(0);
151 tryCompare(track0ProgressBar, "visible", true);
149 tryCompare(track0ProgressBar, "visible", true);
152
150
153 // Continue playback
151 // Continue playback
154 mouseClick(track0PlayButton);
152 mouseClick(track0PlayButton);
155− tryCompare(audio, "playbackState", Audio.PlayingState);
153+ compare(DashAudioPlayer.playing, true);
156 checkPlayerSource(0);
154 checkPlayerSource(0);
157
155
158 // Playing track 1 should make progress bar 1 visible and hide progress bar 0 again
156 // Playing track 1 should make progress bar 1 visible and hide progress bar 0 again
159 mouseClick(track1PlayButton);
157 mouseClick(track1PlayButton);
160
158
161− tryCompare(audio, "playbackState", Audio.PlayingState);
159+ compare(DashAudioPlayer.playing, true);
162 checkPlayerSource(1);
160 checkPlayerSource(1);
163
161
164 // Check the playlist is song 0, 1, 2
162 // Check the playlist is song 0, 1, 2
165− checkPlayerUrls(tracksModel2["tracks"][0].source, audio.playlist.itemSource(0));
163+ checkPlayerUrls(tracksModel2["tracks"][0].source, DashAudioPlayer.playlist.itemSource(0));
166− checkPlayerUrls(tracksModel2["tracks"][1].source, audio.playlist.itemSource(1));
164+ checkPlayerUrls(tracksModel2["tracks"][1].source, DashAudioPlayer.playlist.itemSource(1));
167− checkPlayerUrls(tracksModel2["tracks"][2].source, audio.playlist.itemSource(2));
165+ checkPlayerUrls(tracksModel2["tracks"][2].source, DashAudioPlayer.playlist.itemSource(2));
168
166
169 tryCompare(track0ProgressBar, "visible", false);
167 tryCompare(track0ProgressBar, "visible", false);
170 tryCompare(track1ProgressBar, "visible", true);
168 tryCompare(track1ProgressBar, "visible", true);
@@ -173,7 +171,7 @@ Rectangle {
173 // Playing track 2 should make progress bar 1 visible and hide progress bar 0 again
171 // Playing track 2 should make progress bar 1 visible and hide progress bar 0 again
174 mouseClick(track2PlayButton);
172 mouseClick(track2PlayButton);
175
173
176− tryCompare(audio, "playbackState", Audio.PlayingState);
174+ compare(DashAudioPlayer.playing, true);
177 checkPlayerSource(2);
175 checkPlayerSource(2);
178
176
179 tryCompare(track0ProgressBar, "visible", false);
177 tryCompare(track0ProgressBar, "visible", false);