文章目录
一、媒体播放(Playing Media)
1. 元素 MediaPlayer
1.1 概述
MediaPlayer 是 Qt Multimedia 模块里最核心的媒体控制元素,用来加载、解码并播放 音频或视频文件。它本身不显示视频画面(只负责解码),需要配合 VideoOutput 元素来显示视频。
- 如果只是播放音频,可以单独使用 MediaPlayer 或 Audio 元素。
- 如果要播放视频,需要 MediaPlayer + VideoOutput。
1.2 导入模块
使用 MediaPlayer 需要引入 QtMultimedia:
import QtMultimedia 5.12 // Qt5
// Qt6 则用: import QtMultimedia
1.3 常用属性

1.4 常用方法

1.5 常用信号

1.6 使用示例
播放音频:
import QtQuick 2.12
import QtMultimedia 5.12
import QtQuick.Controls 2.15
Rectangle {
width: 400; height: 200
MediaPlayer {
id: music
source: "qrc:/sounds/music.mp3"
autoPlay: true
volume: 0.8
onError: console.log("播放错误:", errorString)
}
Row {
anchors.centerIn: parent
spacing: 10
Button { text: "播放"; onClicked: music.play() }
Button { text: "暂停"; onClicked: music.pause() }
Button { text: "停止"; onClicked: music.stop() }
}
}
播放视频:
import QtQuick 2.12
import QtMultimedia 5.12
import QtQuick.Controls 2.12
Rectangle {
width: 800; height: 600
MediaPlayer {
id: video
source: "file:///C:/Videos/test.mp4"
autoPlay: true
}
VideoOutput {
anchors.fill: parent
source: video
}
Slider {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
from: 0
to: video.duration
value: video.position
onMoved: video.seek(value)
}
}
2. 元素 VideoOutput
2.1 概述
- VideoOutput 负责 显示 视频画面,但不负责播放。
- 播放功能由 MediaPlayer 提供,VideoOutput.source 绑定到 MediaPlayer,才能看到画面。
- 可以当成一个“视频显示区域”,和 Image 类似,但显示的内容是视频流。
2.2 导入模块
import QtMultimedia 5.12 // Qt5
// Qt6 则用: import QtMultimedia
2.3 常用属性

fillMode 取值:
- VideoOutput.Stretch → 拉伸填充整个区域(可能变形)
- VideoOutput.PreserveAspectFit → 保持比例缩放,完整显示(常用)
- VideoOutput.PreserveAspectCrop → 保持比例缩放并裁剪,铺满显示
2.4 常用信号

2.5 基本用法
播放视频示例:
import QtQuick 2.12
import QtMultimedia 5.12
import QtQuick.Controls 2.12
Rectangle {
width: 800; height: 600
color: "black"
MediaPlayer {
id: player
source: "file:///C:/Videos/sample.mp4"
autoPlay: true
}
VideoOutput {
anchors.fill: parent
source: player
fillMode: VideoOutput.PreserveAspectFit
}
Row {
spacing: 10
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
padding: 10
Button { text: "播放"; onClicked: player.play() }
Button { text: "暂停"; onClicked: player.pause() }
Button { text: "停止"; onClicked: player.stop() }
}
}
显示摄像头画面:VideoOutput 也能显示摄像头(和 Camera 元素配合)
import QtQuick 2.12
import QtMultimedia 5.12
Rectangle {
width: 640; height: 480
Camera { id: cam }
VideoOutput {
anchors.fill: parent
source: cam
fillMode: VideoOutput.PreserveAspectFit
}
}
二、声音效果(Sounds Effects)
2.1 概述
在 QML / Qt Multimedia 里,除了 MediaPlayer、Audio 用于播放音乐或长音频之外,还提供了专门的 SoundEffect 元素 用来播放短音效(比如按钮点击声、提示音、游戏里的爆炸声)。
- SoundEffect 适合 短小、重复的音效,因为它会把音频加载到内存里,播放延迟非常低。
- 不适合播放长音频(比如背景音乐),那应该用 Audio 或 MediaPlayer。
2.2 导入模块
import QtMultimedia 5.12 // Qt5
// Qt6 则用: import QtMultimedia
2.3 常用属性

2.4 常用方法

2.4使用示例
播放按钮点击音效:
import QtQuick 2.12
import QtMultimedia 5.12
import QtQuick.Controls 2.12
Rectangle {
width: 400; height: 200
SoundEffect {
id: clickSound
source: "qrc:/sounds/click.wav"
volume: 0.8
}
Button {
anchors.centerIn: parent
text: "点我"
onClicked: clickSound.play()
}
}
循环播放音效:
SoundEffect {
id: alarmSound
source: "qrc:/sounds/alarm.wav"
loops: SoundEffect.Infinite
}
// 开始循环
alarmSound.play()
// 停止
alarmSound.stop()
注意事项:
- 适合短音效(< 1MB 左右),因为它会一次性加载到内存。
- 文件格式:最稳定的是 WAV,压缩格式(mp3/ogg)支持依赖平台。
- 低延迟:和 MediaPlayer 不同,SoundEffect 播放时几乎没有延迟,很适合游戏或交互反馈。
- 多实例播放:同一个 SoundEffect 不能同时重叠播放,如果需要多个声音叠加,最好创建多个 SoundEffect 实例。
三、捕捉图像(Capturing Images)
3.1 概述
- Camera 元素用于控制和访问设备摄像头。
- 它本身 不显示画面,需要配合 VideoOutput 来预览视频。
- 可以用来:拍照(静态图片)、录像(结合 MediaRecorder)、实时视频预览
3.2 导入模块
import QtMultimedia 5.12 // Qt5
// Qt6: import QtMultimedia
3.3 常用属性

3.4 常用方法
- start() :启动摄像头(相当于 active = true)
- stop() :关闭摄像头
3.5 常用信号

3.6 基本使用
摄像头预览:
import QtQuick 2.12
import QtMultimedia 5.12
import QtQuick.Controls 2.12
Rectangle {
width: 640
height: 480
Camera {
id: cam
captureMode: Camera.CaptureStillImage
}
VideoOutput {
anchors.fill: parent
source: cam
focus: visible // 点击对焦
}
Button {
text: cam.active ? "关闭" : "打开"
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
onClicked: cam.active = !cam.active
}
}
拍照并保存:
import QtQuick 2.12
import QtMultimedia 5.12
import QtQuick.Controls 2.12
Rectangle {
width: 640
height: 480
Camera {
id: cam
captureMode: Camera.CaptureStillImage
imageCapture {
onImageCaptured: (id, preview) => {
console.log("拍照完成,预览图已生成")
}
onImageSaved: (id, fileName) => {
console.log("照片已保存:", fileName)
}
}
}
VideoOutput {
anchors.fill: parent
source: cam
}
Button {
text: "拍照"
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
onClicked: cam.imageCapture.captureToFile("photo.jpg")
}
}
录像示例(配合 MediaRecorder):
Camera {
id: cam
captureMode: Camera.CaptureVideo
}
MediaRecorder {
id: recorder
mediaObject: cam
outputLocation: "file:///C:/Videos/test.mp4"
}
// 开始录像
recorder.record()
// 停止录像
recorder.stop()
Camera 中常见的捕获模式:
Camera.CaptureStillImage // 捕获静态图像(拍照)
Camera.CaptureVideo // 捕获视频(录像)
完整的拍照和录像切换示例:
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtMultimedia 5.12
ApplicationWindow {
visible: true
width: 800
height: 600
title: "拍照 & 录像 示例"
// 相机
Camera {
id: camera
captureMode: Camera.CaptureStillImage // 默认拍照模式
// 拍照功能
imageCapture {
onImageCaptured: {
console.log("图片捕获成功:", preview)
}
onImageSaved: {
console.log("图片保存路径:", path)
}
}
// 录像功能
videoRecorder {
onRecordingStarted: {
console.log("录像开始")
}
onRecordingStopped: {
console.log("录像停止,文件路径:", actualLocation)
}
}
}
// 视频预览窗口
VideoOutput {
source: camera
anchors.fill: parent
focus : visible
}
// 控制栏
Row {
spacing: 10
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
padding: 10
// 模式切换按钮
Button {
text: camera.captureMode === Camera.CaptureStillImage ? "切换到录像" : "切换到拍照"
onClicked: {
if (camera.captureMode === Camera.CaptureStillImage) {
camera.captureMode = Camera.CaptureVideo
} else {
camera.captureMode = Camera.CaptureStillImage
}
}
}
// 拍照按钮
Button {
text: "拍照"
enabled: camera.captureMode === Camera.CaptureStillImage
onClicked: {
camera.imageCapture.captureToLocation("photo_" + Date.now() + ".jpg")
}
}
// 开始录像按钮
Button {
text: "开始录像"
enabled: camera.captureMode === Camera.CaptureVideo
onClicked: {
camera.videoRecorder.recordToLocation("video_" + Date.now() + ".mp4")
camera.videoRecorder.record()
}
}
// 停止录像按钮
Button {
text: "停止录像"
enabled: camera.captureMode === Camera.CaptureVideo
onClicked: camera.videoRecorder.stop()
}
}
}
完整的相机应用示例(支持预览、拍照、保存、录像):
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtMultimedia 5.12
ApplicationWindow {
width: 800
height: 600
visible: true
title: "QML 相机应用"
Camera {
id: cam
captureMode: Camera.CaptureVideo // 默认支持拍照和录像
active: true
// 拍照
imageCapture {
onImageCaptured: (id, preview) => {
console.log("拍照完成,生成预览图")
}
onImageSaved: (id, fileName) => {
console.log("照片已保存到:", fileName)
}
}
}
// 录像功能
MediaRecorder {
id: recorder
mediaObject: cam
outputLocation: "file:///C:/Videos/test.mp4"
onRecordingStarted: console.log("开始录像...")
onRecordingStopped: console.log("录像已保存:", actualLocation)
}
// 显示视频预览
VideoOutput {
anchors.fill: parent
source: cam
focus: visible
fillMode: VideoOutput.PreserveAspectFit
}
// 控制面板
Row {
spacing: 10
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
padding: 10
Button {
text: "拍照"
onClicked: cam.imageCapture.captureToFile("photo.jpg")
}
Button {
text: recorder.recorderState === MediaRecorder.RecordingState ? "停止录像" : "开始录像"
onClicked: {
if (recorder.recorderState === MediaRecorder.RecordingState) {
recorder.stop()
} else {
recorder.record()
}
}
}
Button {
text: cam.active ? "关闭相机" : "打开相机"
onClicked: cam.active = !cam.active
}
}
}
四、播放列表(Implementing a Playlist)
4.1 基本概念
- MediaPlayer:负责播放媒体文件(音频或视频)。
- MediaPlaylist:管理一组媒体文件,可以顺序播放、循环播放、随机播放等。
MediaPlayer 的 playlist 属性可以绑定一个 MediaPlaylist 实例。
4.2 导入模块
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtMultimedia 5.12
4.3 MediaPlaylist 常用属性

播放模式(playbackMode):
- MediaPlaylist.CurrentItemOnce → 播放当前媒体一次
- MediaPlaylist.CurrentItemInLoop → 当前媒体循环播放
- MediaPlaylist.Sequential → 顺序播放列表
- MediaPlaylist.Loop → 播放列表循环
- MediaPlaylist.Random → 随机播放
4.3 MediaPlaylist 常用方法

4.4 基本示例
音频播放列表示例:
ApplicationWindow {
visible: true
width: 400
height: 200
MediaPlayer {
id: player
autoPlay: true
}
MediaPlaylist {
id: playlist
currentIndex: 0
playbackMode: MediaPlaylist.Sequential
MediaContent { source: "qrc:/sounds/song1.mp3" }
MediaContent { source: "qrc:/sounds/song2.mp3" }
MediaContent { source: "qrc:/sounds/song3.mp3" }
}
Component.onCompleted: player.playlist = playlist
Column {
spacing: 10
anchors.centerIn: parent
Button { text: "上一首"; onClicked: playlist.previous() }
Button { text: player.playbackState === MediaPlayer.PlayingState ? "暂停" : "播放";
onClicked: {
if(player.playbackState === MediaPlayer.PlayingState) player.pause()
else player.play()
}
}
Button { text: "下一首"; onClicked: playlist.next() }
}
}
视频播放列表示例:
MediaPlayer {
id: videoPlayer
autoPlay: true
}
MediaPlaylist {
id: videoPlaylist
currentIndex: 0
playbackMode: MediaPlaylist.Loop
MediaContent { source: "file:///C:/Videos/video1.mp4" }
MediaContent { source: "file:///C:/Videos/video2.mp4" }
}
Component.onCompleted: videoPlayer.playlist = videoPlaylist
VideoOutput {
anchors.fill: parent
source: videoPlayer
}
完整的 QML 播放器带播放列表,支持:
- 播放列表显示
- 播放 / 暂停
- 上一首 / 下一首
- 播放模式切换(顺序 / 循环 / 随机)
- 播放状态显示
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtMultimedia 5.12
ApplicationWindow {
visible: true
width: 500
height: 400
title: "QML 播放器示例"
MediaPlayer {
id: player
autoPlay: false
volume: 0.8
}
MediaPlaylist {
id: playlist
currentIndex: 0
playbackMode: MediaPlaylist.Sequential
MediaContent { source: "qrc:/sounds/song1.mp3" }
MediaContent { source: "qrc:/sounds/song2.mp3" }
MediaContent { source: "qrc:/sounds/song3.mp3" }
}
Component.onCompleted: player.playlist = playlist
Column {
anchors.fill: parent
anchors.margins: 20
spacing: 10
// 播放列表显示
ListView {
id: listView
height: 200
model: playlist.mediaCount
delegate: Rectangle {
width: listView.width
height: 40
color: index === playlist.currentIndex ? "#a0c4ff" : "#ffffff"
border.color: "#888888"
Text {
anchors.centerIn: parent
text: playlist.mediaAt(index).source
font.pointSize: 12
elide: Text.ElideRight
}
MouseArea {
anchors.fill: parent
onClicked: playlist.currentIndex = index
}
}
}
// 控制按钮
Row {
spacing: 10
Button {
text: "上一首"
onClicked: playlist.previous()
}
Button {
text: player.playbackState === MediaPlayer.PlayingState ? "暂停" : "播放"
onClicked: {
if(player.playbackState === MediaPlayer.PlayingState)
player.pause()
else
player.play()
}
}
Button {
text: "下一首"
onClicked: playlist.next()
}
}
// 播放模式切换
Row {
spacing: 10
Text { text: "播放模式:" }
ComboBox {
model: ["顺序", "循环", "随机"]
currentIndex: 0
onCurrentIndexChanged: {
switch(currentIndex) {
case 0: playlist.playbackMode = MediaPlaylist.Sequential; break;
case 1: playlist.playbackMode = MediaPlaylist.Loop; break;
case 2: playlist.playbackMode = MediaPlaylist.Random; break;
}
}
}
}
// 播放状态显示
Text {
text: "当前播放: " + playlist.currentMedia.source
font.bold: true
color: "#333333"
}
}
}
673

被折叠的 条评论
为什么被折叠?



