前言
无论是手机端还是电脑端,很多时候我们需要展示视频,但是功能性又不用那么强大,达不到专门使用第三方的插件,这个时候就是官方播放器出场了。
我现在是用qml开发ios,当然效果一般是在mac os上预览了,所以这是用就用到Qt 的多媒体库(QtMultimedia)了。
效果图
说明和代码
视频播放器的功能性,就是普通的视频播放具有的功能,比如微博中的视频,一般包括进度条、开始暂停和静音。
之前我犯了一个致命错误,就是我忘记在pro文件里加多媒体的库了,神奇的是他可以在电脑端播放视频,但是在ios是无法播放的。所以在报错为[qml] The QMediaPlayer object does not have a valid service时,查看你是不是和我犯一样的错误!
QT += multimedia
媒体文件是通过MediaPlayer来控制的,但是展示确实通过另一个类VideoOutput。MediaPlayer主要是控制媒体文件的播放暂停、音量、时长、媒体信息等等一系列东西;而VideoOutput则控制显示的东西,比如展示框的大小、是否自适应方向、平铺的模式等,都是他控制的。
还有一点需要提醒的是:视频源 我是播放的是网页的(http/https),并不是本地的,所以这时候记得配置Info.plist文件(Mac 端的Info.plist在app的包含内容里面),如下图所示。
若是本地的,路径记得记得加上"file://"
MediaPlayer {
id: player
source: "file://video.webm"
autoPlay: true
}
VideoOutput和MediaPlayer的使用都比较简单,对照着帮助文档就可以看懂,所里这里我直接给出代码了。
import QtQuick 2.13
import QtQuick.Controls 2.12
import QtMultimedia 5.13
import QtQuick.Layouts 1.13
Rectangle {
id:root ;
color: "#000000";
MediaPlayer{
id:mediaPlayer;
audioRole: MediaPlayer.VideoRole;
source: "http://*********/ABUIABA6GAAg9Le1-wUo79qQ_AU.mp4";
onError: {
console.log(errorString);
}
}
VideoOutput{
anchors.fill:parent;
source: mediaPlayer;
//flushMode: VideoOutput.LastFrame;
}
//播放按钮
Rectangle {
id: startButton
property bool isPlay: false
width: parent.width / 4
height: width
anchors.centerIn: parent;
color: "transparent";
MouseArea {
anchors.fill: parent
onClicked: {
if (mediaPlayer.playbackState !== Audio.PlayingState) {
mediaPlayer.play();
imageForStart.visible=false;
} else {
mediaPlayer.pause()
imageForStart.visible=true;
}
}
}
Image {
id: imageForStart;
visible: true;
anchors.centerIn: parent
width: parent.width - 5
height: parent.height - 5
source: "qrc:/res/bofang.png";
}
}
//进度条和静音按钮
Rectangle {
id: progressRow;
visible: true
height: parent.height / 9
anchors{left: parent.left; right: parent.right; bottom: parent.bottom;}
color: "transparent";
Text {
id: durationTime
anchors{verticalCenter: parent.verticalCenter; left: parent.left; leftMargin: 10;}
color: "#ffffff";
font{pointSize: 12; family: "PingFang SC";weight: Font.Medium;}
text: {
var milliseconds = mediaPlayer.position
var minutes = Math.floor(milliseconds / 60000)
milliseconds -= minutes * 60000
var seconds = milliseconds / 1000
seconds = Math.round(seconds)
if (seconds < 10)
return minutes + ":0" + seconds
else
return minutes + ":" + seconds
}
}
Slider {
id: durationTimeSlider
height: parent.height
anchors{verticalCenter: parent.verticalCenter; left: durationTime.right; leftMargin: 10;
right: endTime.left; rightMargin: 10;}
value: mediaPlayer.position / mediaPlayer.duration
background: Rectangle {
x: durationTimeSlider.leftPadding
y: durationTimeSlider.topPadding
+ durationTimeSlider.availableHeight / 2 - height / 2
implicitWidth: 200
implicitHeight: 4
width: durationTimeSlider.availableWidth
height: implicitHeight
radius: 2
color: "#bdbebf"
Rectangle {
width: durationTimeSlider.visualPosition * parent.width
height: parent.height
color: "red";
radius: 2
}
}
handle: Rectangle {
antialiasing: true
x: durationTimeSlider.leftPadding + durationTimeSlider.visualPosition
* (durationTimeSlider.availableWidth - width)
y: durationTimeSlider.topPadding
+ durationTimeSlider.availableHeight / 2 - height / 2
implicitWidth: 15
implicitHeight: 15
radius: 10
//color: durationTimeSlider.pressed ? "#f0f0f0" : "#f6f6f6"
border.width: durationTimeSlider.pressed ? 3 : 2
border.color: durationTimeSlider.pressed ? "silver" : "#bdbebf"
Rectangle {
width: 4
height: 4
radius: 2
color: "red"
anchors.centerIn: parent
}
}
property real index: 0
property bool changed: false
onMoved: {
if (pressed) {
index = position
}
}
onPressedChanged: {
if (pressed === true) {
changed = true
} else if (changed === true) {
mediaPlayer.seek(index * mediaPlayer.duration)
changed = false
}
}
}
Text {
id: endTime;
anchors{verticalCenter: parent.verticalCenter; right: volumeBtn.left; rightMargin: 5;}
color: "#ffffff";
font{pointSize: 12; family: "PingFang SC"; weight: Font.Medium;}
text: {
var milliseconds = mediaPlayer.duration.valueOf()
var minutes = Math.floor(milliseconds / 60000)
milliseconds -= minutes * 60000
var seconds = milliseconds / 1000
seconds = Math.round(seconds)
if (seconds < 10)
return minutes + ":0" + seconds
else
return minutes + ":" + seconds /* return m + ":" + s*/
}
}
Rectangle {
id: volumeBtn;
width: 25; height: 25;
color: "#00000000";
anchors{right: parent.right; rightMargin: 10; verticalCenter: parent.verticalCenter;}
Image {
id: voiceImage
anchors.fill: parent
source: mediaPlayer.muted ? "qrc:/res/jingyin.png" : "qrc:/res/yinliang.png";
}
MouseArea {
anchors.fill: parent
onClicked: {
mediaPlayer.muted = !mediaPlayer.muted
}
}
}
}
}
结束语
这篇博客同样是为了我以后的复制粘贴!