Planned maintenance has been done but it did not solve the problem. So work will continue on this and a new time for trying updates will be announced asap.

QML audio playlist || stop a song when other one is played + autoplay on finish



  • I'm trying to build a music player, I was able to play/pause music on click but a song keeps playing after choosing another one, also how do I make my app autoplay the next song after finishing the current one?
    This is my current playlist code:

    AppListView {
                    model: pathModel      ///C++ model contains all music URLs 
                    delegate:Rectangle{
                        id: rect
                        height: page.height/6
                        width: page.width
                        anchors.topMargin: (page.height/height)*(modelData.indexOf(model.fileURL)-1)
                        Audio {
                            id: playMusic
                            source: modelData
                        }
                        Text{
                            id: ooo
                            text: Qt.resolvedUrl(modelData).slice(Qt.resolvedUrl(modelData).lastIndexOf("/")+1,Qt.resolvedUrl(modelData).lastIndexOf("."))  //to print only song's name
                            anchors.horizontalCenter: parent.horizontalCenter
                            anchors.verticalCenter: parent.verticalCenter
                            font.pixelSize: 20
                        }
                        MouseArea {
                            id: playAreafiles
                            anchors.fill: parent
                            onClicked: {
                                if (Audio.playbackState === Audio.PlayingState){ //auto stopping the audio before playing failed
                                    Audio.stop() 
                                    Audio.play()
                                }
                                if((playMusic.playbackState === Audio.PlayingState))
                                    playMusic.pause()  //pause if clicked while playing
                                else
                                    playMusic.play() //play otherwise
                            }
                        }
                    }
                }
    

    I have no idea how the autoplay next song works too, any help will be appreciated.



  • Hi @newbiSoso
    As per my understanding the problem in your code is that in ListView every ListElement has its own copy of Audio & MouseArea and you can play and pause the same song only on clicking the same element.
    When you click on the other element the previous element's AudioPlayback state is not affected.

    Can you please have a look at Playlist QML Type, might help you.

    Or you have to change the way you handle the Audio in your ListView {}



  • @Pradeep-P-N I tried using Playlist type but didn't know how to pass my model to it, it's a c++ model that contains the URL's of my music:

    static QStringList pathList;
    
    ….
    int main(int argc, char *argv[]){
    …..
    QDirIterator it("E:/", QStringList() << "*.mp3", QDir::Files, QDirIterator::Subdirectories);
            while (it.hasNext()){
                qDebug() << it.next();
                pathList.append(it.next());
            }
        QQmlContext *ctxt1 = engine.rootContext();
        ctxt1->setContextProperty("pathModel", QVariant::fromValue(pathList)); //used model pathmodel
    
    ….
    }
    


  • Hi @newbiSoso ,

    • l dont think so there is a prebuilt property in Audio which will let you pause a song when another song is playing and autoplay a song when a song is completed.You need to write your own logic for them.

    Note:- I have never worked or tried with Playlist though, so as @Pradeep-P-N suggested you can have a look into its documentation for more information about it.

    • I have used Audio and have written a sample code with features like

      • Play/Pause

      • Pausing the previous song when the new song is clicked.

      • Auto-playing the next song when the current song is over.

    Sample Code:-

     ListModel {
        id: audioDummyModel
    
        ListElement {
            audioURL: "file:///C:\\Users\\USHRINI\\Music\\One.mp3"
            playState: false
        }
    
        ListElement {
            audioURL: "file:///C:\\Users\\USHRINI\\Music\\One.mp3"
            playState: false
        }
    
        ListElement {
            audioURL: "file:///C:\\Users\\USHRINI\\Music\\Two.mp3"
            playState: false
        }
    
        ListElement {
            audioURL: "file:///C:\\Users\\USHRINI\\Music\\Two.mp3"
            playState: false
        }
    }
    
    ListView {
        anchors.fill: parent
        spacing: 10
        model: audioDummyModel
    
        delegate:Rectangle{
            id: rect
    
            height: 100
            width: 300
            color: "cyan"
            border.color: activeFocus?"red":"black"
            border.width: 4
    
            Audio {
                id: playMusic
    
                source: audioURL
    
                property bool tempPlayBackState: playState
    
                onTempPlayBackStateChanged: {
                    console.log("Temp State:",index,tempPlayBackState)
                    if(tempPlayBackState) {
                        playMusic.play()
                        rect.forceActiveFocus()
                    } else {
                        playMusic.stop()
                    }
                }
    
                onStopped: {
                    console.log("Stopped",index,status)
                    if(status === 7) {
                        playState = !playState
    
                        if(index > -1 && index < audioDummyModel.count - 1) {
                            audioDummyModel.setProperty(index+1, "playState", true);
                        }
                    }
                }
            }
    
            onActiveFocusChanged:  {
                console.log("Focus:",focus,index)
                playState = focus
            }
    
            Text{
                text: audioURL
                anchors.centerIn: parent
            }
    
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    console.log("Focus on Click",rect.activeFocus)
                    if(rect.activeFocus) {
                        switch (playMusic.playbackState) {
                        case 1:
                            playMusic.pause();
                            break;
                        case 2:
                            playMusic.play()
                            break;
                        }
                    } else {
                        rect.forceActiveFocus()
                    }
                }
            }
        }
    }
    

    Sample Output:-

    0_1559551526609_13b14110-c3d3-45ed-ba32-044b07e92f98-image.png

    The song which is currently playing or paused will be highlighted in red.

    Note:- Just copy paste the code and specify your own URL model, i have just written a dummy model in qml. So first try with just 2 or 3 songs from a harcoded path, if they work then you can specify your C++ model.I guess the code can be optimized more, but its just a sample code so if its working according to your expectations and features then after that you can optimize the code.



  • Thanks for sharing this information. It's really helpful. Do i need a gmail account created from gmail accounts free list for playing this playlist?