on xenial help sign in
Create the DashAudioPlayer

We will use it to unify playing in both previews and cards (coming soon)

commit9d12c181a9062d520069ba26c788b46ad5b54479 authorAlbert Astals Cid <albert.astals@canonical.com> dateMon 11 May 2015, 15:41 (11 years ago) parent4b2834c
4 files changed+88−60
qml/Dash/DashAudioPlayer/DashAudioPlayer.qml+63 qml/Dash/DashAudioPlayer/qmldir+1 qml/Dash/Previews/PreviewAudioPlayback.qml+20−52 tests/qmltests/Dash/Previews/tst_PreviewAudioPlayback.qml+4−8
qml/Dash/DashAudioPlayer/DashAudioPlayer.qmlnew file+63
@@ -0,0 +1,63 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+pragma Singleton
18+import QtQuick 2.4
19+
20+import QtMultimedia 5.0
21+
22+QtObject {
23+ readonly property real progress: audio.position / audio.duration
24+ readonly property bool playing: audio.playbackState === Audio.PlayingState
25+ readonly property bool paused: audio.playbackState === Audio.PausedState
26+ readonly property bool stopped: audio.playbackState === Audio.StoppedState
27+
28+ property alias source: audio.source
29+
30+ function stop() {
31+ audio.stop();
32+ }
33+
34+ function play() {
35+ audio.play();
36+ }
37+
38+ function pause() {
39+ audio.pause();
40+ }
41+
42+ property QtObject d: Audio {
43+ id: audio
44+ objectName: "audio"
45+
46+ onErrorStringChanged: console.warn("Dash Audio player error:", errorString)
47+ }
48+
49+ function lengthToString(s) {
50+ if (typeof(s) !== "number" || s <= 0) return "";
51+
52+ var sec = "" + s % 60;
53+ if (sec.length == 1) sec = "0" + sec;
54+ var hour = Math.floor(s / 3600);
55+ if (hour < 1) {
56+ return Math.floor(s / 60) + ":" + sec;
57+ } else {
58+ var min = "" + Math.floor(s / 60) % 60;
59+ if (min.length == 1) min = "0" + min;
60+ return hour + ":" + min + ":" + sec;
61+ }
62+ }
63+}
qml/Dash/DashAudioPlayer/qmldirnew file+1
@@ -0,0 +1 @@
1+singleton DashAudioPlayer 1.0 DashAudioPlayer.qml
qml/Dash/Previews/PreviewAudioPlayback.qml+20−52
@@ -15,8 +15,8 @@
1515 */
1616
1717import QtQuick 2.0
18−import QtMultimedia 5.0
1918import Ubuntu.Components 0.1
19+import "../DashAudioPlayer"
2020
2121/*! \brief Preview widget for audio tracks.
2222
@@ -36,38 +36,6 @@ PreviewWidget {
3636 id: root
3737 height: childrenRect.height
3838
39− onIsCurrentPreviewChanged: if (!isCurrentPreview) audio.stop()
40−
41− Audio {
42− id: audio
43− objectName: "audio"
44−
45− property real progress: audio.position / audio.duration
46− property Item playingItem
47−
48− Component.onDestruction: {
49− // destroying the component doesn't automatically send stop to the media service, probably a bug in QtMultimedia
50− audio.stop();
51− }
52−
53− onErrorStringChanged: console.warn("Audio player error:", errorString)
54−
55− function lengthToString(s) {
56− if (typeof(s) !== "number" || s <= 0) return "";
57−
58− var sec = "" + s % 60;
59− if (sec.length == 1) sec = "0" + sec;
60− var hour = Math.floor(s / 3600);
61− if (hour < 1) {
62− return Math.floor(s / 60) + ":" + sec;
63− } else {
64− var min = "" + Math.floor(s / 60) % 60;
65− if (min.length == 1) min = "0" + min;
66− return hour + ":" + min + ":" + sec;
67− }
68− }
69− }
70−
7139 Column {
7240 anchors { left: parent.left; right: parent.right }
7341 visible: trackRepeater.count > 0
@@ -78,19 +46,19 @@ PreviewWidget {
7846 model: root.widgetData["tracks"]
7947
8048 function play(item, source) {
81− audio.stop();
49+ DashAudioPlayer.stop();
8250 // Make sure we change the source, even if two items point to the same uri location
83− audio.source = "";
84− audio.source = source;
85− audio.playingItem = item;
86− audio.play();
51+ DashAudioPlayer.source = "";
52+ DashAudioPlayer.source = source;
53+ DashAudioPlayer.play();
8754 }
8855
8956 delegate: Item {
9057 id: trackItem
9158 objectName: "trackItem" + index
9259
93− property bool isPlayingItem: audio.playingItem == trackItem
60+ readonly property url sourceUrl: modelData["source"]
61+ readonly property bool isPlayingItem: DashAudioPlayer.source == sourceUrl
9462
9563 anchors { left: parent.left; right: parent.right }
9664 height: units.gu(5)
@@ -98,9 +66,9 @@ PreviewWidget {
9866 Row {
9967 id: trackRow
10068
101− property int column1Width: units.gu(3)
102− property int column2Width: width - (2 * spacing) - column1Width - column3Width
103− property int column3Width: units.gu(4)
69+ readonly property int column1Width: units.gu(3)
70+ readonly property int column2Width: width - (2 * spacing) - column1Width - column3Width
71+ readonly property int column3Width: units.gu(4)
10472
10573 anchors.verticalCenter: parent.verticalCenter
10674 width: parent.width
@@ -110,7 +78,7 @@ PreviewWidget {
11078 objectName: "playButton"
11179 width: trackRow.column1Width
11280 height: width
113− iconSource: audio.playbackState == Audio.PlayingState && trackItem.isPlayingItem ? "image://theme/media-playback-pause" : "image://theme/media-playback-start"
81+ iconSource: DashAudioPlayer.playing && trackItem.isPlayingItem ? "image://theme/media-playback-pause" : "image://theme/media-playback-start"
11482
11583 // Can't be "transparent" or "#00xxxxxx" as the button optimizes away the surrounding shape
11684 // FIXME when this is resolved: https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1251685
@@ -118,13 +86,13 @@ PreviewWidget {
11886
11987 onClicked: {
12088 if (trackItem.isPlayingItem) {
121− if (audio.playbackState == Audio.PlayingState) {
122− audio.pause();
123− } else if (audio.playbackState == Audio.PausedState) {
124− audio.play();
89+ if (DashAudioPlayer.playing) {
90+ DashAudioPlayer.pause();
91+ } else if (DashAudioPlayer.paused) {
92+ DashAudioPlayer.play();
12593 }
12694 } else {
127− trackRepeater.play(trackItem, modelData["source"]);
95+ trackRepeater.play(trackItem, sourceUrl);
12896 }
12997 }
13098 }
@@ -164,14 +132,14 @@ PreviewWidget {
164132 id: progressBarFill
165133 objectName: "progressBarFill"
166134
167− property int maxWidth: progressBarImage.width - units.dp(4)
135+ readonly property int maxWidth: progressBarImage.width - units.dp(4)
168136
169137 anchors {
170138 left: progressBarImage.left
171139 right: progressBarImage.right
172140 verticalCenter: progressBarImage.verticalCenter
173141 margins: units.dp(2)
174− rightMargin: maxWidth - (maxWidth * audio.progress) + units.dp(2)
142+ rightMargin: maxWidth - (maxWidth * DashAudioPlayer.progress) + units.dp(2)
175143 }
176144 height: units.dp(2)
177145 visible: progressBarImage.visible
@@ -182,7 +150,7 @@ PreviewWidget {
182150 id: progressBarImage
183151 anchors { left: parent.left; top: parent.bottom; right: parent.right }
184152 height: units.dp(6)
185− visible: audio.playbackState != Audio.StoppedState && trackItem.isPlayingItem && modelData["length"] > 0
153+ visible: !DashAudioPlayer.stopped && trackItem.isPlayingItem && modelData["length"] > 0
186154 source: "graphics/music_progress_bg.png"
187155 }
188156 }
@@ -196,7 +164,7 @@ PreviewWidget {
196164 color: scopeStyle ? scopeStyle.foreground : Theme.palette.normal.baseText
197165 fontSize: "small"
198166 horizontalAlignment: Text.AlignRight
199− text: audio.lengthToString(modelData["length"])
167+ text: DashAudioPlayer.lengthToString(modelData["length"])
200168 }
201169 }
202170 }
tests/qmltests/Dash/Previews/tst_PreviewAudioPlayback.qml+4−8
@@ -18,6 +18,7 @@ import QtQuick 2.0
1818import QtTest 1.0
1919import Ubuntu.Components 0.1
2020import "../../../../qml/Dash/Previews"
21+import "../../../../qml/Dash/DashAudioPlayer"
2122import Unity.Test 0.1 as UT
2223import QtMultimedia 5.0
2324
@@ -67,8 +68,7 @@ Rectangle {
6768 }
6869
6970 function test_time_formatter(data) {
70− var audio = findInvisibleChild(previewAudioPlayback, "audio");
71− compare(audio.lengthToString(data.value), data.result)
71+ compare(DashAudioPlayer.lengthToString(data.value), data.result)
7272 }
7373
7474 function test_tracks_data() {
@@ -102,7 +102,7 @@ Rectangle {
102102
103103 function checkPlayerSource(index) {
104104 var modelFilename = previewAudioPlayback.widgetData["tracks"][index]["source"].replace(/^.*[\\\/]/, '');
105− var playerFilename = findInvisibleChild(previewAudioPlayback, "audio").source.toString().replace(/^.*[\\\/]/, '');
105+ var playerFilename = DashAudioPlayer.source.toString().replace(/^.*[\\\/]/, '');
106106
107107 compare(modelFilename, playerFilename, "Player source is not set correctly.");
108108 }
@@ -123,7 +123,7 @@ Rectangle {
123123 var track1PlayButton = findChild(track1Item, "playButton");
124124 var track2PlayButton = findChild(track2Item, "playButton");
125125
126− var audio = findInvisibleChild(previewAudioPlayback, "audio");
126+ var audio = DashAudioPlayer.d;
127127
128128 // All progress bars must be hidden in the beginning
129129 compare(track0ProgressBar.visible, false);
@@ -170,10 +170,6 @@ Rectangle {
170170 tryCompare(track0ProgressBar, "visible", false);
171171 tryCompare(track1ProgressBar, "visible", false);
172172 tryCompare(track2ProgressBar, "visible", true);
173−
174− // Changing preview should make all players shut up!
175− previewAudioPlayback.isCurrentPreview = false
176− tryCompare(audio, "playbackState", Audio.StoppedState);
177173 }
178174 }
179175}