En esta página

Ejemplo de reproductor multimedia QML

Reproducción de audio y vídeo utilizando el tipo QML MediaPlayer.

Reproductor de vídeo con controles de reproducción y área de previsualización de vídeo

Este ejemplo muestra un sencillo reproductor multimedia que puede reproducir archivos de audio y vídeo utilizando varios códecs.

Ejecución del ejemplo

Para ejecutar el ejemplo desde Qt Creatorabra el modo Welcome y seleccione el ejemplo de Examples. Para más información, consulta Qt Creator: Tutorial: Construir y ejecutar.

Instanciando el MediaPlayer

El punto de entrada para el código QML en este ejemplo es Main.qml. Aquí se crea un ApplicationWindow y se establecen propiedades como id, title, width y height.

ApplicationWindow {
    id: root
    title: qsTr("Multimedia Player")
    width: 1280
    height: 720

A continuación se crea MediaPlayer y se definen las dos propiedades responsables de la salida de vídeo y audio. En primer lugar, videoOutput que representa el visor de vídeo y en segundo lugar audioOutput que proporciona la salida de audio para el reproductor.

MediaPlayer {
    id: mediaPlayer
    ...
videoOutput: videoOutput
audioOutput: AudioOutput {
    id: audio
    muted: playbackController.muted
    volume: playbackController.volume
}
    ...
VideoOutput {
    id: videoOutput
    anchors.fill: parent
    visible: mediaPlayer.mediaStatus > 0

    TapHandler {
        onDoubleTapped: {
            root.fullScreen ?  root.showNormal() : root.showFullScreen()
            root.fullScreen = !root.fullScreen
        }
    }
}

La propiedad visible del tipo VideoOutput se establece en true cuando la propiedad mediaStatus del tipo MediaPlayer es mayor que 0. mediaStatus es de tipo enumeración y es igual a 0 cuando No media has been set, y mayor que 0 en caso contrario. Por lo tanto, VideoOutput es visible cuando se ha establecido el medio.

El tipo MediaPlayer tiene una propiedad de señal llamada onErrorOccurred que puede ser anulada específicamente para manejar errores. En este caso la señal abre un MessageDialog utilizando el método open() y establece su propiedad text en una propiedad MediaPlayer llamada errorString.

onErrorOccurred: {
    mediaError.text = mediaPlayer.errorString
    mediaError.open()
}

Controles de reproducción

Para tener un reproductor multimedia utilizable, es necesario que haya una interfaz para controlar la reproducción. Ésta se crea en su propio archivo de componentes, PlaybackControl.qml, y se instancia en Main.qml.

PlaybackControl {
    id: playbackController
    ...
onTracksChanged: {
    audioTracksInfo.read(mediaPlayer.audioTracks)
    videoTracksInfo.read(mediaPlayer.videoTracks)
    subtitleTracksInfo.read(mediaPlayer.subtitleTracks, 6) /* QMediaMetaData::Language = 6 */
    updateMetadata()
    mediaPlayer.play()
}

Cuando se crea, se envían objetos a este tipo, como información de pista, información de metadatos y el propio objeto MediaPlayer. En PlaybackControl.qml, cada uno de estos objetos tiene una required property, lo que significa que estas propiedades deben establecerse cuando se crea el objeto PlaybackControl.

Item {
    id: playbackController

    required property MediaPlayer mediaPlayer
    required property MetadataInfo metadataInfo
    required property TracksInfo audioTracksInfo
    required property TracksInfo videoTracksInfo
    required property TracksInfo subtitleTracksInfo

Estos controles de reproducción pueden dividirse en secciones. En la parte superior izquierda del panel se encuentra una colección de botones que sirven para abrir un archivo, ya sea seleccionándolo desde un explorador de archivos o introduciendo una URL. El archivo se carga en MediaPlayer estableciendo la propiedad source. Ambos botones se instancian utilizando un CustomButton custom component .

CustomButton {
    id: fileDialogButton
    icon.source: "../images/open_new.svg"
    flat: false
    onClicked: fileDialog.open()
}

CustomButton {
    id: openUrlButton
    icon.source: "../images/link.svg"
    flat: false
    onClicked: urlPopup.open()
}

Se crean tres botones centrados en este panel, que se encargan de reproducir, pausar y buscar diez segundos hacia atrás o hacia delante. Los medios se reproducen y pausan utilizando los métodos play() y pause(), respectivamente. Para saber cuándo dibujar un botón de reproducción o pausa, se consulta la propiedad playbackState. Por ejemplo, cuando es igual al valor enum MediaPlayer.PlayingState entonces se dibuja el botón de pausa.

CustomRoundButton {
    id: playButton
    visible: playbackController.mediaPlayer.playbackState !== MediaPlayer.PlayingState
    icon.source: "../images/play_symbol.svg"
    onClicked: playbackController.mediaPlayer.play()
}

CustomRoundButton {
    id: pauseButton
    visible: playbackController.mediaPlayer.playbackState === MediaPlayer.PlayingState
    icon.source: "../images/pause_symbol.svg"
    onClicked: playbackController.mediaPlayer.pause()
}

Para navegar diez segundos hacia delante o hacia atrás, el position del tipo MediaPlayer se incrementa en 10.000 milisegundos y se establece utilizando el método setPosition().

CustomRoundButton {
    id: forward10Button
    icon.source: "../images/forward10.svg"
    onClicked: {
        const pos = Math.min(playbackController.mediaPlayer.duration,
                           playbackController.mediaPlayer.position + 10000)
        playbackController.mediaPlayer.setPosition(pos)
    }
}

Búsqueda de reproducción y audio

En PlaybackControl.qml, se instancian un tipo AudioControl y otro PlaybackSeekControl. Ambos están definidos en su propio archivo de componentes y son responsables del control de volumen y la búsqueda de reproducción, respectivamente. El tipo AudioControl define un botón para silenciar y un Slider, de QtQuick Controls, para ajustar el volumen del reproductor. Ambos atributos se exponen mediante la definición de una propiedad mute y volume y se accede a ellos desde la definición AudioOutput en Main.qml.

property alias muted: muteButton.checked
property real volume: slider.value

PlaybackSeekControl utiliza un RowLayout que contiene un Slider con un Text a cada lado. Los dos elementos de Text muestran la hora actual y el tiempo restante del medio que se está reproduciendo. Ambos se calculan utilizando dos propiedades del tipo MediaPlayer, position, que indica la posición de reproducción actual en milisegundos, y duration, que indica la duración del medio en milisegundos.

Label {
    id: currentTime
    Layout.preferredWidth: 45
    text: seekController.formatToMinutes(seekController.mediaPlayer.position)
    horizontalAlignment: Text.AlignLeft
    font.pixelSize: 11
}
    ...
Label {
    id: remainingTime
    Layout.preferredWidth: 45
    text: seekController.formatToMinutes(seekController.mediaPlayer.duration - seekController.mediaPlayer.position)
    horizontalAlignment: Text.AlignRight
    font.pixelSize: 11
}

La propiedad Slider sólo se activa cuando el reproductor multimedia es buscable y no, por ejemplo, cuando se trata de medios en directo. El tipo MediaPlayer tiene una propiedad para esto llamada seekable. El value del Slider se calcula utilizando las propiedades position y duration del MediaPlayer.

enabled: seekController.mediaPlayer.seekable
value: seekController.mediaPlayer.position / seekController.mediaPlayer.duration

Metadatos e información de pista

El tipo PlaybackControl instancia un SettingsPopup, que contiene información sobre los metadatos del medio cargado actualmente y la selección de pistas, así como la capacidad de actualizar la velocidad de reproducción. Este Popup se define en SettingsPopup.qml.

Ajustes de reproducción e información de metadatos seleccionables por el usuario

Los metadatos están contenidos en su propio archivo de componentes, MetadataInfo.qml. Contiene un ListModel, una función para borrarlos, clear(), y una función para rellenarlos, read(MediaMetadata metadata). La función read(MediaMetadata metadata) toma como parámetro un objeto de tipo MediaMetaData, y navega por su estructura clave-valor para extraer sus datos en el model del ListView. Los métodos utilizados para ello son keys(), que devuelve todas las claves del MediaMetaData, y {stringValue(Clave clave)}, que devuelve el value para un key dado.

function read(metadata) {
    if (!metadata)
        return
    for (const key of metadata.keys())
        if (metadata.stringValue(key))
            listModel.append({
                                name: metadata.metaDataKeyToString(key),
                                value: metadata.stringValue(key)
                            })
}

ListModel {
    id: listModel
}

A continuación, los datos se muestran en SettingsPopup.qml en un tipo ListView. El delegate de este ListView es una fila de dos elementos Text, correspondientes a los pares clave-valor abstraídos del elemento MediaMetaData.

Al otro lado de Popup hay controles de velocidad de reproducción y selección de pista para audio, vídeo y subtítulos. La velocidad de reproducción se elige a partir de un ComboBox y se establece mediante la propiedad playbackRate.

settingsController.mediaPlayer.playbackRate = (currentIndex + 1) * 0.25

El tipo llamado TracksInfo, definido en TracksInfo.qml, contiene los datos sobre las pistas. Más concretamente, un ListModel que contiene los títulos de las pistas, o para los subtítulos específicamente, los idiomas. Esta información se rellena en Main.qml llamando a la función read(MediaMetadata mediaMetadata) definida en el tipo TracksInfo.

onTracksChanged: {
    audioTracksInfo.read(mediaPlayer.audioTracks)
    videoTracksInfo.read(mediaPlayer.videoTracks)
    subtitleTracksInfo.read(mediaPlayer.subtitleTracks, 6) /* QMediaMetaData::Language = 6 */
    updateMetadata()
    mediaPlayer.play()
}

El model definido en TracksInfo es entonces consultado en el ComboBoxes en el SettingsPopup para seleccionar la pista actual.

settingsController.mediaPlayer.pause()
tracksInfo.selectedTrack = currentIndex
settingsController.mediaPlayer.play()

Proyecto de ejemplo @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.