使用Audio API中的playlist来做一个音乐播放器

在最新的QtMultiMedia 5.6中,AudioAPI中有一个playlist属性.我们可以充分利用这个属性来做一个简单的音乐播放器.在我们的官方文档中,写的是QttMultiMedia 5.4.正确的是5.6版本.Audio API可以让我们很方便地播放我们所需要的音乐.在我们之前的文章"如何在Ubuntu QML应用中播放音乐"也讨论过如何利用MediaPlayerSoundEffect来播放音乐.


如何利用Audio 中的playlist呢?我们先来看一个简单的例子:


        Audio {
            id: player;
            autoPlay: true
            autoLoad: true
            playlist: Playlist {
                id: playlist
            }

            Component.onCompleted: {
                console.log(playlist.addItem(Qt.resolvedUrl("sounds/song1.mp3")))
                console.log(playlist.addItem(Qt.resolvedUrl("sounds/background.mp3")))
                console.log("playlist count: " + playlist.itemCount)
                console.log("metaData type: " + typeof(meta))

                play()
            }
        }

在上面的代码中,我们向我们的playlist表中添加我们的音乐文件.当然,我们也可以动态地添加它们到我们的列表中.我们也可以通过如下的方式来添加我们的音乐列表:


    Audio {
        id: player;
        playlist: Playlist {
            id: playlist
            PlaylistItem { source: "song1.ogg"; }
            PlaylistItem { source: "song2.ogg"; }
            PlaylistItem { source: "song3.ogg"; }
        }
    }
    ListView {
        model: playlist;
        delegate: Text {
            font.pixelSize: 16;
            text: source;
        }
    }

目前在Ubuntu手机上测试.这种方法有一个 bug.如果音乐文件存在的话,那么在列表中将会有两个相同的项被显示.目前,我们还是使用前面介绍的方法来做我们的例程.


Main.qml

import QtQuick 2.4
import Ubuntu.Components 1.3
import QtMultimedia 5.6

MainView {
    // objectName for functional testing purposes (autopilot-qt5)
    objectName: "mainView"

    // Note! applicationName needs to match the "name" field of the click manifest
    applicationName: "playlist.liu-xiao-guo"

    width: units.gu(60)
    height: units.gu(85)
    property var meta: player.metaData

    Page {
        id: page
        header: PageHeader {
            id: pageHeader
            title: i18n.tr("playlist")
        }

        Audio {
            id: player;
            autoPlay: true
            autoLoad: true
            playlist: Playlist {
                id: playlist
            }

            Component.onCompleted: {
                console.log(playlist.addItem(Qt.resolvedUrl("sounds/song1.mp3")))
                console.log(playlist.addItem(Qt.resolvedUrl("sounds/background.mp3")))
                console.log("playlist count: " + playlist.itemCount)
                console.log("metaData type: " + typeof(meta))

                console.log("The properties of metaData is:")
                var keys = Object.keys(meta);
                for( var i = 0; i < keys.length; i++ ) {
                    var key = keys[ i ];
                    var data = key + ' : ' + meta[ key ];
                    console.log( key + ": " + data)
                }

                play()
            }
        }

        Flickable {
            anchors {
                left: parent.left
                right: parent.right
                top: pageHeader.bottom
                bottom: parent.bottom
            }
            contentHeight: layout.childrenRect.height +
                           layout1.height + layout1.spacing

            Column {
                id: layout
                anchors.fill: parent

                ListView {
                    anchors.left: parent.left
                    anchors.right: parent.right
                    height: page.height/2

                    model: playlist;
                    delegate: Label {
                        fontSize: "x-large"
                        text: {
                            var filename = String(source);
                            var name = filename.split("/").pop();
                            return name;
                        }

                        MouseArea {
                            anchors.fill: parent

                            onClicked: {
                                if (player.playbackState != Audio.PlayingState) {
                                    player.playlist.currentIndex = index;
                                    player.play();
                                } else {
                                    player.pause();
                                }
                            }
                        }
                    }
                }

                Rectangle {
                    width: parent.width
                    height: units.gu(0.1)
                    color: "red"
                }

                Slider {
                    id: defaultSlider
                    anchors.horizontalCenter: parent.horizontalCenter
                    width: parent.width * 0.8
                    maximumValue: 100
                    value: player.position/player.duration * maximumValue
                }

                CustomListItem {
                    title.text:  {
                        switch (player.availability ) {
                        case Audio.Available:
                            return "availability: available";
                        case Audio.Busy:
                            return "availability: Busy";
                        case Audio.Unavailable:
                            return "availability: Unavailable";
                        case Audio.ResourceMissing:
                            return "availability: ResourceMissing";
                        default:
                            return "";
                        }
                    }
                }

                CustomListItem {
                    title.text: "bufferProgress: " + player.bufferProgress;
                }

                CustomListItem {
                    title.text: "duration: " + player.duration/1000 + " sec"
                }

                CustomListItem {
                    title.text: "hasAudio: " + player.hasAudio
                }

                CustomListItem {
                    title.text: "hasVideo: " + player.hasVideo
                }

                CustomListItem {
                    title.text: "loops: " + player.loops
                }

                CustomListItem {
                    title.text: "muted: " + player.muted
                }

                CustomListItem {
                    title.text: "playbackRate: " + player.playbackRate
                }

                CustomListItem {
                    title.text: {
                        switch (player.playbackState) {
                        case Audio.PlayingState:
                            return "playbackState : PlayingState"
                        case Audio.PausedState:
                            return "playbackState : PausedState"
                        case Audio.StoppedState:
                            return "playbackState : StoppedState"
                        default:
                            return ""
                        }
                    }
                }

                CustomListItem {
                    title.text: "seekable: " + player.seekable
                }

                CustomListItem {
                    title.text: "url: " + String(player.source)
                }

                CustomListItem {
                    title.text: "volume: " + player.volume
                }

                CustomListItem {
                    title.text: {
                        switch (player.status) {
                        case Audio.NoMedia:
                            return "status: NoMedia"
                        case Audio.Loading:
                            return "status: Loading"
                        case Audio.Loaded:
                            return "status: Loaded"
                        case Audio.Buffering:
                            return "status: Buffering"
                        case Audio.Stalled:
                            return "status: Stalled"
                        case Audio.Buffered:
                            return "status: Buffered"
                        case Audio.EndOfMedia:
                            return "status: EndOfMedia"
                        case Audio.InvalidMedia:
                            return "status: InvalidMedia"
                        case Audio.UnknownStatus:
                            return "status: UnknownStatus"
                        default:
                            return ""
                        }
                    }
                }

            }
        }

        Row {
            id: layout1
            anchors.bottom: parent.bottom
            anchors.bottomMargin: units.gu(1)
            anchors.horizontalCenter: parent.horizontalCenter
            spacing: units.gu(5)

            Button {
                text: "Previous"
                onClicked: {
                    console.log("Previouse is clicked")
                    var previousIndex = player.playlist.previousIndex(1)
                    console.log("previousIndex: " + player.playlist.previousIndex(1))
                    if ( previousIndex == -1 ) {
                        player.playlist.currentIndex = player.playlist.itemCount - 1;
                    } else {
                        player.playlist.previous();
                    }

                    player.play()
                }
            }

            Button {
                text: "Next"
                onClicked: {
                    console.log("Next is clicked")
                    var nextIndex = player.playlist.nextIndex(1)
                    console.log("nextIndex: " + nextIndex )
                    if (nextIndex == -1) {
                        player.playlist.currentIndex = 0
                    } else {
                        player.playlist.next();
                    }

                    player.play();
                }
            }
        }
    }
}

整个的设计还是非常简单.屏幕的上面是一个音乐的列表.下面是一个该音乐文件的状态.由于一些原因,我们目前还不能得到音乐文件的metaData.

    


我们可以通过点击列表中的像来播放或停止正在播放的音乐.





评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值