on 91cc9f2 help sign in
unity8/qml/Components/MediaServices/VideoPlayerControls.qml
158 lines 5.0 kB history raw
1/*
2 * Copyright (C) 2016 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 */
17import QtQuick 2.4
18import QtQuick.Layouts 1.1
19import QtMultimedia 5.0
20import Ubuntu.Components 1.3
22MediaServicesControls {
23 id: root
24 readonly property alias mediaPlayer: _mediaPlayer
25 property bool interacting: false
27 QtObject {
28 id: priv
30 function formatProgress(time) {
31 time = Math.floor(time / 1000);
33 var secs = time % 60;
34 time = Math.floor(time / 60);
35 var min = time % 60;
36 var hour = Math.floor(time / 60);
38 if (secs < 10) secs = "0%1".arg(secs);
39 if (min < 10) min = "0%1".arg(min);
40 if (hour > 0) {
41 // TRANSLATORS: this refers to a duration/remaining time of the video in hours, minutes and seconds,
42 // of which you can change the order.
43 // %1 refers to hours, %2 refers to minutes and %3 refers to seconds.
44 return i18n.tr("%1:%2:%3").arg(hour).arg(min).arg(secs);
45 } else {
46 // TRANSLATORS: this refers to a duration/remaining time of the video in minutes and seconds,
47 // of which you can change the order.
48 // %1 refers to minutes and %2 refers to seconds.
49 return i18n.tr("%1:%2").arg(min).arg(secs);
50 }
51 }
52 }
54 component: Item {
55 Connections {
56 target: mediaPlayer
57 onPositionChanged: {
58 if (slider.valueGuard) return;
60 slider.valueGuard = true;
61 slider.value = mediaPlayer.position;
62 slider.valueGuard = false;
63 if (!slider.pressed) {
64 positionLabel.text = priv.formatProgress(mediaPlayer.position);
65 }
66 }
67 }
69 Binding {
70 target: root
71 property: "interacting"
72 value: slider.pressed
73 }
75 Label {
76 id: positionLabel
77 anchors {
78 left: parent.left
79 bottom: parent.bottom
80 bottomMargin: -units.dp(3)
81 }
82 verticalAlignment: Text.AlignBottom
83 fontSize: "x-small"
84 color: root.iconColor
86 text: priv.formatProgress(mediaPlayer.position)
87 }
89 Slider {
90 id: slider
91 property bool valueGuard: false
93 anchors {
94 left: parent.left
95 right: parent.right
96 }
97 height: units.gu(2)
98 live: true
99 enabled: mediaPlayer.seekable && mediaPlayer.duration > 0
100 minimumValue: 0
101 maximumValue: mediaPlayer.duration > 0 ? mediaPlayer.duration : 1
102 value: mediaPlayer.position
104 onStyleInstanceChanged: {
105 if (__styleInstance) __styleInstance.backgroundColor = root.iconColor;
106 }
108 onValueChanged: {
109 if (!pressed || slider.valueGuard) return;
111 slider.valueGuard = true;
112 mediaPlayer.seek(value);
113 slider.valueGuard = false;
114 }
116 property bool wasPlaying: mediaPlayer.playbackState === MediaPlayer.PlayingState
117 onPressedChanged: {
118 if (pressed) {
119 wasPlaying = mediaPlayer.playbackState === MediaPlayer.PlayingState
120 mediaPlayer.pause();
121 } else {
122 positionLabel.text = priv.formatProgress(mediaPlayer.position);
123 if (wasPlaying) {
124 mediaPlayer.play();
125 }
126 }
127 }
129 function formatValue(value) {
130 return priv.formatProgress(value);
131 }
132 }
134 Label {
135 anchors {
136 right: parent.right
137 bottom: parent.bottom
138 bottomMargin: -units.dp(3)
139 }
140 verticalAlignment: Text.AlignBottom
141 fontSize: "x-small"
142 color: root.iconColor
144 text: priv.formatProgress(mediaPlayer.duration)
145 }
146 }
148 MediaPlayer {
149 id: _mediaPlayer
150 objectName: "mediaPlayer"
152 onError: {
153 if (error !== MediaPlayer.NoError) {
154 stop();
155 }
156 }
157 }