Forgot an important bit.
This commit is contained in:
parent
c485cedb3d
commit
05b93e1962
1 changed files with 323 additions and 0 deletions
323
qml/pages/components/MediaItem.qml
Normal file
323
qml/pages/components/MediaItem.qml
Normal file
|
@ -0,0 +1,323 @@
|
|||
import QtQuick 2.6
|
||||
import Sailfish.Silica 1.0
|
||||
import QtMultimedia 5.6
|
||||
|
||||
|
||||
|
||||
ListItem {
|
||||
id: item
|
||||
|
||||
property string url
|
||||
property string mediaUrl
|
||||
property string mimeType: 'audio/mp3'
|
||||
property int length
|
||||
|
||||
property bool _isAudio: mimeType.substring(0, 6) === "audio/"
|
||||
property bool _isImage: mimeType.substring(0, 6) === "image/"
|
||||
|
||||
function _toTime(s)
|
||||
{
|
||||
if (s < 0)
|
||||
{
|
||||
return "-";
|
||||
}
|
||||
|
||||
s /= 1000;
|
||||
var seconds = Math.floor(s) % 60;
|
||||
s /= 60;
|
||||
var minutes = Math.floor(s) % 60;
|
||||
s /= 60;
|
||||
var hours = Math.floor(s);
|
||||
|
||||
if (seconds < 10)
|
||||
{
|
||||
seconds = "0" + seconds;
|
||||
}
|
||||
if (minutes < 10)
|
||||
{
|
||||
minutes = "0" + minutes;
|
||||
}
|
||||
|
||||
if (hours > 0)
|
||||
{
|
||||
return hours + ":" + minutes + ":" + seconds;
|
||||
}
|
||||
else
|
||||
{
|
||||
return minutes + ":" + seconds;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns the filename of the given URL.
|
||||
*/
|
||||
function _urlFilename(url) {
|
||||
var idx = url.lastIndexOf("=");
|
||||
if (idx !== -1) {
|
||||
return url.substring(idx + 1);
|
||||
}
|
||||
|
||||
idx = url.lastIndexOf("/");
|
||||
if (idx === url.length - 1) {
|
||||
idx = url.substring(0, idx).lastIndexOf("/");
|
||||
}
|
||||
|
||||
if (idx !== -1) {
|
||||
return url.substring(idx + 1);
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
/* Returns the icon source for the given media.
|
||||
*/
|
||||
function _mediaIcon(url, type) {
|
||||
if (type.substring(0, 6) === "image/") {
|
||||
return url;
|
||||
} else if (type.substring(0, 6) === "video/") {
|
||||
return "image://theme/icon-l-play";
|
||||
} else {
|
||||
return "image://theme/icon-m-other";
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns a user-friendly media type name for the given MIME type.
|
||||
*/
|
||||
function _mediaTypeName(type) {
|
||||
if (type.substring(0, 6) === "image/") {
|
||||
return qsTr("Image");
|
||||
} else if (type.substring(0, 6) === "video/") {
|
||||
return qsTr("Video");
|
||||
} else if (type === "application/pdf") {
|
||||
return qsTr("PDF document");
|
||||
} else {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
console.log('MediaItem')
|
||||
console.log(url)
|
||||
console.log(mediaUrl)
|
||||
if (_isAudio)
|
||||
{
|
||||
if (audioProxy.playing)
|
||||
{
|
||||
audioProxy.pause();
|
||||
}
|
||||
else
|
||||
{
|
||||
audioProxy.play();
|
||||
}
|
||||
}
|
||||
else if (_isImage)
|
||||
{
|
||||
var props = {
|
||||
"url": item.url,
|
||||
"name": _urlFilename(item.url)
|
||||
}
|
||||
pageStack.push(Qt.resolvedUrl("ImagePage.qml"), props);
|
||||
}
|
||||
else
|
||||
{
|
||||
Qt.openUrlExternally(item.url);
|
||||
}
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: audioProxy
|
||||
|
||||
property bool _active: audioPlayer.source == source
|
||||
property bool playing: _active ? audioPlayer.playing
|
||||
: false
|
||||
property bool paused: _active ? audioPlayer.paused
|
||||
: false
|
||||
property real duration: _active ? audioPlayer.duration
|
||||
: -1
|
||||
property real position: _active ? audioPlayer.position
|
||||
: 0
|
||||
|
||||
property string source: _isAudio ? item.url : ""
|
||||
|
||||
property Timer _seeker: Timer {
|
||||
interval: 50
|
||||
|
||||
onTriggered: {
|
||||
if (audioProxy._active)
|
||||
{
|
||||
if (! audioPlayer.playing)
|
||||
{
|
||||
console.log("Stream is not ready. Deferring seek operation.")
|
||||
_seeker.start();
|
||||
}
|
||||
else
|
||||
{
|
||||
audioPlayer.seek(Math.max(0, database.audioBookmark(audioProxy.source) - 3000));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function play()
|
||||
{
|
||||
if (_active)
|
||||
{
|
||||
audioPlayer.play();
|
||||
}
|
||||
else
|
||||
{
|
||||
// save bookmark before switching to another podcast
|
||||
if (audioPlayer.playing)
|
||||
{
|
||||
database.setAudioBookmark(audioPlayer.source,
|
||||
audioPlayer.position);
|
||||
}
|
||||
|
||||
audioPlayer.stop();
|
||||
audioPlayer.source = source;
|
||||
audioPlayer.play();
|
||||
_seeker.start();
|
||||
}
|
||||
}
|
||||
|
||||
function pause()
|
||||
{
|
||||
if (_active)
|
||||
{
|
||||
//database.setAudioBookmark(source, audioPlayer.position);
|
||||
audioPlayer.pause();
|
||||
}
|
||||
}
|
||||
|
||||
function seek(value)
|
||||
{
|
||||
if (_active) audioPlayer.seek(value);
|
||||
}
|
||||
|
||||
onPositionChanged: {
|
||||
if (_active)
|
||||
{
|
||||
if (! slider.down)
|
||||
{
|
||||
slider.value = position;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onDurationChanged: {
|
||||
if (_active)
|
||||
{
|
||||
slider.maximumValue = duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
Audio {
|
||||
id: audioPlayer
|
||||
property bool playing: playbackState === Audio.PlayingState
|
||||
property bool paused: playbackState === Audio.PausedState
|
||||
autoLoad: false
|
||||
autoPlay: false
|
||||
}
|
||||
Image {
|
||||
id: mediaIcon
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Theme.paddingLarge
|
||||
anchors.rightMargin: Theme.paddingMedium
|
||||
width: height
|
||||
height: parent.height
|
||||
asynchronous: true
|
||||
smooth: true
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
sourceSize.width: width * 2
|
||||
sourceSize.height: height * 2
|
||||
source: ! _isAudio ? _mediaIcon(item.url, item.mimeType)
|
||||
: audioProxy.playing ? "image://theme/icon-l-pause"
|
||||
: "image://theme/icon-l-play"
|
||||
clip: true
|
||||
|
||||
BusyIndicator {
|
||||
running: parent.status === Image.Loading
|
||||
anchors.centerIn: parent
|
||||
size: BusyIndicatorSize.Medium
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
id: mediaNameLabel
|
||||
|
||||
anchors.left: mediaIcon.right
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: Theme.paddingLarge
|
||||
anchors.rightMargin: Theme.paddingLarge
|
||||
truncationMode: TruncationMode.Fade
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
color: Theme.primaryColor
|
||||
text: _urlFilename(item.url)
|
||||
}
|
||||
Label {
|
||||
id: label1
|
||||
anchors.top: mediaNameLabel.bottom
|
||||
anchors.left: mediaNameLabel.left
|
||||
font.pixelSize: Theme.fontSizeExtraSmall
|
||||
color: Theme.secondaryColor
|
||||
text: ! slider.visible ? _mediaTypeName(item.mimeType)
|
||||
: audioProxy.playing ? _toTime(slider.sliderValue)
|
||||
: _toTime(database.audioBookmark(audioProxy.source))
|
||||
|
||||
}
|
||||
Label {
|
||||
id: label2
|
||||
anchors.top: mediaNameLabel.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Theme.paddingLarge
|
||||
font.pixelSize: Theme.fontSizeExtraSmall
|
||||
color: Theme.secondaryColor
|
||||
text: slider.visible ? _toTime(audioProxy.duration)
|
||||
: item.length >= 0 ? Format.formatFileSize(item.length)
|
||||
: ""
|
||||
}
|
||||
|
||||
Slider {
|
||||
id: slider
|
||||
|
||||
visible: _isAudio
|
||||
enabled: audioProxy.playing || audioProxy.paused
|
||||
|
||||
anchors.left: label1.right
|
||||
anchors.right: label2.left
|
||||
anchors.verticalCenter: label1.verticalCenter
|
||||
|
||||
leftMargin: Theme.paddingSmall
|
||||
rightMargin: Theme.paddingSmall
|
||||
height: Theme.itemSizeSmall / 3
|
||||
|
||||
handleVisible: false
|
||||
minimumValue: 0
|
||||
|
||||
onDownChanged: {
|
||||
if (! down)
|
||||
{
|
||||
audioProxy.seek(sliderValue);
|
||||
if (! audioProxy.playing)
|
||||
{
|
||||
audioProxy.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}//Slider
|
||||
IconButton {
|
||||
id: mediaDlBtn
|
||||
icon.source: "image://theme/icon-m-cloud-download"
|
||||
anchors {
|
||||
right: parent.right
|
||||
rightMargin: Theme.horizontalPageMargin
|
||||
bottom: parent.bottom
|
||||
bottomMargin: Theme.horizontalPageMargin
|
||||
}
|
||||
onClicked: {
|
||||
var filename = url.split("/")
|
||||
FileDownloader.downloadFile(url, filename[filename.length-1])
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue