C++ con QT para desarrollar un reproductor de música (QML+QT)

Escrito al frente, este artículo se reproduce del blog de CSDN: https://blog.csdn.net/xyygudu/article/details/130134269 , autor: xyygudu

código de dirección

xyygudu/Player: Qt y QML implementan un reproductor de video y de música (github.com)

Visualización de efectos parciales

inserte la descripción de la imagen aquí

Funciones implementadas

Relacionado con video: pausa de reproducción, ajuste de progreso de reproducción, ajuste de volumen, visualización de lista de archivos de video en el directorio especificado

Relacionado con el audio: reproducción en pausa, canción anterior, siguiente canción, reproducción aleatoria y reproducción secuencial, ajuste del progreso de la reproducción, desplazamiento y resaltado de letras, visualización de la lista de archivos de audio en el directorio especificado

Otras funciones: admite cambio de máscara, maximización y minimización de ventanas, ajuste de forma arbitraria de ventana, movimiento de ventana, sombra de borde

descripción del archivo principal

inserte la descripción de la imagen aquí

reproducción de vídeo

Ideas de implementación

La lista de videos se implementa a través de TableView, y los datos que mostrará su delegado provienen de m_videoTableModel de videoplayer.h. Cuando se hace doble clic en una fila de la lista, se activa una señal personalizada en VideoTable.qml y la señal cambia la página a VideoSecondPage.qml ( doubleClicked(int row)página de reproducción de video) y, al mismo tiempo, pase el número de línea en el que se hizo doble clic a VideoSecondPage.qml, de modo que VideoSecondPage.qml pueda llamar a la función C++ de acuerdo con el número de línea para obtener la ruta de video correspondiente a la línea actual en la que se hizo doble clic, para que el video se pueda reproducir

// 切换页面并传递行号 VideoPanel.qml
VideoFirstPage {
    
    
  onTableRowDoubleClicked: {
    
      // 其实就是VideoTable.qml的doubleClicked信号
    root.selectedRow = row  // 将选中的行号赋值给root.selectedRow便于传入到secondPage中
    stackView.push(secondPage)   // 跳转到第二个页面(播放视频的页面)
  }
}// 视频播放器 VideoSecondPage.qml
VideoPlayer {
    
    
  id: videoPlayer
  anchors.left: parent.left
  anchors.right: parent.right
  height: width * 9 / 16
  source: myVideoPlayer.getVideoPathByRow(root.selectedRow)
}

Reproductor de música

Ideas de implementación

Implementación de reproducción de audio: la lista de audio se implementa a través de TableView, y los datos que mostrará su delegado (delegado) provienen de m_musicTableModel de musicplayer.h. Cuando se hace doble clic en una fila de la lista, aparece una señal personalizada en MusicTable.qml se activa, y la señal cambia el número de fila en el que se hizo doble clic doubleClicked(int row)Páselo a MusicControlBar.qml (que controla la reproducción de audio y otras páginas), para que MusicControlBar.qml pueda llamar a la función C++ de acuerdo con el número de línea para obtener la ruta de video correspondiente a la línea de doble clic actual, para que el video se pueda reproducir

Implementación de canción anterior/canción siguiente: MusicControlBar.qml tiene una canción anterior y un botón de canción siguiente. Para cambiar de canción, solo necesita cambiar la propiedad selectedRow de MusicControlBar.qml. La fila seleccionada registra qué fila de la música que se está reproduciendo actualmente está en el lista. Después de hacer clic en la siguiente canción, simplemente aumente la fila seleccionada en 1, no se requieren otras operaciones, porque la propiedad de origen de MediaPlayer (ubicada en MusicControlBar.qml) está vinculada a la fila seleccionada, siempre que la fila seleccionada cambie, la fuente de MediaPlayer también será el cambio correspondiente, y el cambio de fuente activará la señal onSourceChanged, onSourceChanged realiza la reproducción de audio, el código principal es el siguiente:

// 下一曲按钮
CusWidgets.ImageButton {
    
    
    ...省略代码一万行
    onClicked: {
    
    
        if (root.playMode === root.order) {
    
    // 如果是顺序播放
            if (root.seclectedRow !== -1) {
    
    
                if (root.seclectedRow === myMusicPlayer.musicTableModel.rowCount()-1) {
    
    
                    root.seclectedRow = 0
                } else {
    
    
                    root.seclectedRow += 1
                }
            } else {
    
    
                root.seclectedRow = 0
            }
        } else {
    
     // 如果是随机播放
            root.seclectedRow = getRandomNum(0, myMusicPlayer.musicTableModel.rowCount())
        }
    }
}
​
MediaPlayer {
    
    
    id: musicPlayer
    source: root.seclectedRow === -1 ? "" : myMusicPlayer.getMusicPathByRow(root.seclectedRow)
    onSourceChanged: {
    
    
        musicPlayer.play()
    }
}

Implementación de visualización de letras:

(1) Actualice el modelo de letras: como se mencionó anteriormente, solo necesita cambiar la propiedad seclectedRow personalizada de MusicControlBar.qml para cortar canciones. Cuando se cambia seclectedRow, la señal activada por este puede actualizar el modelo de letras.

MusicControlBar {
    
     // 位于MusicPanel.qml
    id: musicControlBar
    onSeclectedRowChanged: {
    
    
        myMusicPlayer.upDateLyricModelBy(seclectedRow) //调用C++函数来更新歌词信息
    }
}

(2) Implementación del desplazamiento de letras: El archivo de letras LRC es el siguiente:

// 第一个数字表示分钟,第二个数字表示秒,第三个数字可能是毫秒
// 不过我们只用到前两个数字和歌词内容
[0:0.250.00]沉默是金 - 张国荣
[0:1.500.00]词:许冠杰
[0:2.190.00]曲:张国荣
[0:27.450.00]夜风凛凛 独回望旧事前尘
[0:33.120.00]是以往的我充满怒愤
​
// 另一种lrc歌词文件格式是下面这样的
// 第一个数字是分钟,第二个数字是秒,第三个数字是多少个10毫秒,也就是说,
// 第三个数最大为100
[ver:v1.0]     // 我的程序为了方便没有解析这些信息
[ti:]          
[00:00.36]- 许巍 
[00:01.04]词:许巍
[00:01.69]曲:许巍
[00:37.95]拥抱着亲人的时候

Después de comprender el formato de la letra, puede analizar la letra a través de expresiones regulares (consulte la función parseLyrics en lyrics.h), que combina la marca de tiempo de la letra (como [0:27.450.00]) y el índice correspondiente a la letra. (el índice marca esto es Las primeras letras, como [0:27.450.00] el índice correspondiente es 3, el índice comienza desde 0) se almacena en QMap, es decir, en m_lyric2IdxMap del siguiente código, la marca de tiempo es la clave, el índice es el valor, y luego el contenido de la letra (como: [0:27.450.00] Correspondiente a la letra: Night Breeze Alone Looking Back at the Past) Almacenado en el modelo de letras LyricModel, LyricModel en realidad administra QStringList . Una vez que se completa el análisis de la letra, el siguiente paso es realizar el desplazamiento de la letra. Como se muestra en el siguiente código, podemos obtener el número de índice de la letra que debe mostrarse actualmente en el procesamiento de la señal onPositionChanged de MediaPlayer. La idea de ​La obtención del índice se basa en el progreso de reproducción de música actual (es decir, la forma Consulte el valor de qint64 pos), recorra el m_lyric2IdxMap anterior, encuentre que pos está en el período de tiempo de la letra y luego devuelva el índice de la letras en LyricModel.

MediaPlayer {
    
          
    onPositionChanged: {
    
    
        // 实时显示歌词 调用c++函数,返回此时应该显示的歌词的索引
        var idx = myMusicPlayer.getLyricIdxByPosition(position)
        if (idx === -1) {
    
    
            root.lyricIdx = -1   // -1表示当前position没有合适的歌词
        } else {
    
    
            root.lyricIdx = idx
        }
    }
}
// c++函数,见musicplayer.cpp
int MusicPlayer::getLyricIdxByPosition(qint64 pos)
{
    
    
     QMap<qint64, int>::iterator iter = m_lyric2IdxMap.begin();
     while (iter != m_lyric2IdxMap.end())
     {
    
    
         if ((iter.key()-500<=pos)  && (iter+1).key()-500 > pos)
         {
    
    
             return iter.value();
         }
         iter++;
     }
     return -1;
}

Después de obtener el índice de letras actual de acuerdo con el progreso de la reproducción, solo necesita asignar el valor del índice de letras a la propiedad currentIndex de ListView que muestra las letras.

ListView {
    
    
  id: lyricsList
  currentIndex: lyricIndex===-1?currentIndex:lyricIndex
  // 省略代码一万行
}

BICHO

Haga clic en el reproductor de audio en la barra de navegación izquierda, luego maximice la ventana, haga clic en el reproductor de video izquierdo y descubrí que la tabla de video no cambia con el ancho de la ventana. No sé por qué, pero ya llamé a forceLayout. () en onWidthChangede de TableView. . Avisame si se soluciona por favor

TableView {
    
    
    id: tableView
    // 省略代码
    columnWidthProvider: function(colum) {
    
     return root.columnWidths[colum] }
    onWidthChanged: {
    
    
        // If you change the values that a rowHeightProvider or a columnWidthProvider
        // return for rows and columns inside the viewport, you must call forceLayout.
        // This informs TableView that it needs to use the provider functions again to
        // recalculate and update the layout.
        forceLayout()
    }
}

Referencias

Realización del cambio de piel: jugando con Qml(3)-cambiando de piel | Blog de Taoge

Análisis de letras: Reproductor de música en red basado en Qt (5) Implementación de desplazamiento de letras y visualización de Qt Desplazamiento de letras Flower Dog Fdog's Blog-CSDN Blog; ListView efecto de desplazamiento hacia arriba en QML_hp_cpp's Blog-CSDN Blog

Visualización de letras: efecto de desplazamiento de ListView en QML - blog de hp_cpp - blog de CSDN

Ajuste de ancho y alto de la ventana: qml elimina la barra de título y arrastra la ventana y cambia el tamaño de la ventana_qml no puede mover la barra de título_Blog de Lin Xingnan-CSDN Blog

Supongo que te gusta

Origin blog.csdn.net/hallobike/article/details/130263803
Recomendado
Clasificación