The Qt 6 Book
Contribute!
Contribute!
  • Preface

    • Welcome!
    • Acknowledgements
    • Authors
  • Meet Qt

    • Qt and Qt Quick
    • Qt Building Blocks
    • Qt 6 Introduction
  • Getting Started

    • Quick Start
    • Installing Qt 6 SDK
    • Hello World
    • Application Types
    • Summary
  • Qt Creator IDE

    • Qt Creator IDE
    • The User Interface
    • Registering your Qt Kit
    • Managing Projects
    • Using the Editor
    • Locator
    • Debugging
    • Shortcuts
  • Quick Starter

    • Quick Starter
    • QML Syntax
    • Core Elements
    • Components
    • Simple Transformations
    • Positioning Elements
    • Layout Items
    • Input Elements
    • Advanced Techniques
  • Fluid Elements

    • Fluid Elements
    • Animations
    • States and Transitions
    • Advanced Techniques
  • QtQuick Controls

    • UI Controls
    • Introduction to Controls
    • An Image Viewer
    • Common Patterns
    • The Imagine Style
    • Summary
  • Model View

    • Model-View-Delegate
    • Concept
    • Basic Models
    • Dynamic Views
    • Delegate
    • Advanced Techniques
    • Summary
  • Canvas

    • Canvas Element
    • Convenience API
    • Gradients
    • Shadows
    • Images
    • Transformation
    • Composition Modes
    • Pixel Buffers
    • Canvas Paint
    • Porting from HTML5 Canvas
  • Shapes

    • Shapes
    • A Basic Shape
    • Building Paths
    • Filling Shapes
    • Animating Shapes
    • Summary
  • Effects

    • Effects in QML
    • Particle Concept
    • Simple Simulation
    • Particle Parameters
    • Directed Particles
    • Affecting Particles
    • Particle Groups
    • Particle Painters
    • Graphics Shaders
    • Shader Elements
    • Fragment Shaders
    • Wave Effect
    • Vertex Shader
    • Curtain Effect
    • Summary
  • Multimedia

    • Multimedia
    • Playing Media
    • Sound Effects
    • Video Streams
    • Capturing Images
    • Summary
  • Qt Quick 3D

    • Qt Quick 3D
    • The Basics
    • Working with Assets
    • Materials and Light
    • Animations
    • Mixing 2D and 3D Contents
    • Summary
  • Networking

    • Networking
    • Serving UI via HTTP
    • Templates
    • HTTP Requests
    • Local files
    • REST API
    • Authentication using OAuth
    • Web Sockets
    • Summary
  • Storage

    • Storage
    • Settings
    • Local Storage - SQL
  • Dynamic QML

    • Dynamic QML
    • Loading Components Dynamically
    • Creating and Destroying Objects
    • Tracking Dynamic Objects
    • Summary
  • Javascript

    • JavaScript
    • Browser/HTML vs Qt Quick/QML
    • JS Language
    • JS Objects
    • Creating a JS Console
  • Qt C++

    • Qt and C++
    • A Boilerplate Application
    • The QObject
    • Build Systems
    • Common Qt Classes
    • Models in C++
  • Extending QML

    • Extending QML with C++
    • Understanding the QML Run-time
    • Plugin Content
    • Creating the plugin
    • FileIO Implementation
    • Using FileIO
    • Summary
  • Qt for Python

    • Qt for Python
    • Introduction
    • Installing
    • Building an Application
    • Limitations
    • Summary
  • Qt for MCUs

    • Qt for MCUs
    • Setup
    • Hello World - for MCUs
    • Integrating with C++
    • Working with Models
    • Summary

Playing Media

The most basic case of multimedia integration in a QML application is for it to playback media. The QtMultimedia module supports this by providing a dedicated QML component: the MediaPlayer.

The MediaPlayer component is a non-visual item that connects a media source to one or several output channel(s). Depending on the nature of the media (i.e. audio, image or video) various output channel(s) can be configured.

Playing audio

In the following example, the MediaPlayer plays a mp3 sample audio file from a remote URL in an empty window:

import QtQuick
import QtMultimedia

Window {
    width: 1024
    height: 768
    visible: true

    MediaPlayer {
        id: player
        source: "https://file-examples.com/wp-content/storage/2017/11/file_example_MP3_2MG.mp3"
        audioOutput: AudioOutput {}
    }

    // #region play
    Component.onCompleted: {
        player.play()
    }
    // #endregion play
}

In this example, the MediaPlayer defines two attributes:

  • source: it contains the URL of the media to play. It can either be embedded (qrc://), local (file://) or remote (https://).
  • audioOutput: it contains an audio output channel, AudioOutput, connected to a physical output device. By default, it will use the default audio output device of the system.

As soon as the main component has been fully initialized, the player’s play function is called:

Component.onCompleted: {
    player.play()
}

Playing a video

If you want to play visual media such as pictures or videos, you must also define a VideoOutput element to place the resulting image or video in the user interface.

In the following example, the MediaPlayer plays a mp4 sample video file from a remote URL and centers the video content in the window:

import QtQuick
import QtMultimedia

Window {
    width: 1920
    height: 1080
    visible: true

    MediaPlayer {
        id: player
        source: "https://file-examples.com/wp-content/storage/2017/04/file_example_MP4_1920_18MG.mp4"
        audioOutput: AudioOutput {}
        videoOutput: videoOutput
    }

    VideoOutput {
        id: videoOutput
        anchors.fill: parent
        anchors.margins: 20
    }

    Component.onCompleted: {
        player.play()
    }
}

In this example, the MediaPlayer defines a third attribute:

  • videoOutput: it contains the video output channel, VideoOutput, representing the visual space reserved to display the video in the user interface.

Tips

Please note that the VideoOutput component is a visual item. As such, it's essential that it is created within the visual components hierarchy and not within the MediaPlayer itself.

Controlling the playback

The MediaPlayer component offers several useful properties. For instance, the duration and position properties can be used to build a progress bar. If the seekable property is true, it is even possible to update the position when the progress bar is tapped.

It's also possible to leverage AudioOutput and VideoOutput properties to customize the experience and provide, for instance, volume control.

The following example adds custom controls for the playback:

  • a volume slider
  • a play/pause button
  • a progress slider
import QtQuick
import QtQuick.Controls
import QtMultimedia

Window {
    id: root
    width: 1920
    height: 1080
    visible: true

    MediaPlayer {
        id: player
        source: Qt.resolvedUrl("sample-5s.mp4")
        audioOutput: audioOutput
        videoOutput: videoOutput
    }

    // #region audio-output
    AudioOutput {
        id: audioOutput
        volume: volumeSlider.value
    }
    // #endregion audio-output

    VideoOutput {
        id: videoOutput
        width: videoOutput.sourceRect.width
        height: videoOutput.sourceRect.height
        anchors.horizontalCenter: parent.horizontalCenter
    }

    // #region volume-slider
    Slider {
        id: volumeSlider
        anchors.top: parent.top
        anchors.right: parent.right
        anchors.margins: 20
        orientation: Qt.Vertical
        value: 0.5
    }
    // #endregion volume-slider

    Item {
        height: 50
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        anchors.margins: 20

        // #region button
        Button {
            anchors.horizontalCenter: parent.horizontalCenter
            text: player.playbackState ===  MediaPlayer.PlayingState ? qsTr("Pause") : qsTr("Play")
            onClicked: {
                switch(player.playbackState) {
                    case MediaPlayer.PlayingState: player.pause(); break;
                    case MediaPlayer.PausedState: player.play(); break;
                    case MediaPlayer.StoppedState: player.play(); break;
                }
            }
        }
        // #endregion button

        // #region progress-slider
        Slider {
            id: progressSlider
            width: parent.width
            anchors.bottom: parent.bottom
            enabled: player.seekable
            value: player.duration > 0 ? player.position / player.duration : 0
            background: Rectangle {
                implicitHeight: 8
                color: "white"
                radius: 3
                Rectangle {
                    width: progressSlider.visualPosition * parent.width
                    height: parent.height
                    color: "#1D8BF8"
                    radius: 3
                }
            }
            handle: Item {}
            onMoved: function () {
                player.position = player.duration * progressSlider.position
            }
        }
        // #endregion progress-slider
    }

    Component.onCompleted: {
        player.play()
    }
}

The volume slider

A vertical Slider component is added on the top right corner of the window, allowing the user to control the volume of the media:

Slider {
    id: volumeSlider
    anchors.top: parent.top
    anchors.right: parent.right
    anchors.margins: 20
    orientation: Qt.Vertical
    value: 0.5
}

The volume attribute of the AudioOutput is then mapped to the value of the slider:

AudioOutput {
    id: audioOutput
    volume: volumeSlider.value
}

Play / Pause

A Button component reflects the playback state of the media and allows the user to control this state:

Button {
    anchors.horizontalCenter: parent.horizontalCenter
    text: player.playbackState ===  MediaPlayer.PlayingState ? qsTr("Pause") : qsTr("Play")
    onClicked: {
        switch(player.playbackState) {
            case MediaPlayer.PlayingState: player.pause(); break;
            case MediaPlayer.PausedState: player.play(); break;
            case MediaPlayer.StoppedState: player.play(); break;
        }
    }
}

Depending on the playback state, a different text will be displayed in the button. When clicked, the corresponding action will be triggered and will either play or pause the media.

Tips

The possible playback states are listed below:

  • MediaPlayer.PlayingState: The media is currently playing.
  • MediaPlayer.PausedState: Playback of the media has been suspended.
  • MediaPlayer.StoppedState: Playback of the media is yet to begin.

Interactive progress slider

A Slider component is added to reflect the current progress of the playback. It also allows the user to control the current position of the playback.

<!-- @include: src/playback-controls/main.qml#progress-slider{5,6,19-21} -->

A few things to note on this sample:

  • This slider will only be enabled when the media is seekable (line 5)
  • Its value will be set to the current media progress, i.e. player.position / player.duration (line 6)
  • The media position will be (also) updated when the slider is moved by the user (lines 19-21)

The media status

When using MediaPlayer to build a media player, it is good to monitor the status property of the player. Here is an enumeration of the possible statuses, ranging from MediaPlayer.Buffered to MediaPlayer.InvalidMedia. The possible values are summarized in the bullets below:

  • MediaPlayer.NoMedia. No media has been set. Playback is stopped.
  • MediaPlayer.Loading. The media is currently being loaded.
  • MediaPlayer.Loaded. The media has been loaded. Playback is stopped.
  • MediaPlayer.Buffering. The media is buffering data.
  • MediaPlayer.Stalled. The playback has been interrupted while the media is buffering data.
  • MediaPlayer.Buffered. The media has been buffered, this means that the player can start playing the media.
  • MediaPlayer.EndOfMedia. The end of the media has been reached. Playback is stopped.
  • MediaPlayer.InvalidMedia. The media cannot be played. Playback is stopped.
  • MediaPlayer.UnknownStatus. The status of the media is unknown.

As mentioned in the bullets above, the playback state can vary over time. Calling play, pause or stop alters the state, but the media in question can also have an effect. For example, the end can be reached, or it can be invalid, causing playback to stop.

Tips

It is also possible to let the MediaPlayer to loop a media item. The loops property controls how many times the source is to be played. Setting the property to MediaPlayer.Infinite causes endless looping. Great for continuous animations or a looping background song.

Help us improve this page!
Last Updated: 11/26/25, 7:55 PM
Contributors: Fabrice SALVAIRE
Prev
Multimedia
Next
Sound Effects