QML 录像及预览的实现
在使用QML做移动端开发时,我们总是会接触到多媒体的开发,尤其在当下这个流媒体时代,拍小视频已经成为了一种风尚,记录每个的生活轨迹,四季变化。
这里通过QML实现简单的录像预览,录像界面如下:
左边显示录像和录像的时间,右边功能控制区域,单击开始时开始计时,开始按钮变成结束,单击结束时界面如下:
进入视频预览,右边功能区,单击丢弃则进入视频初始页面,单击使用则根据个人需求做相应处理,功能基本如上,接下来开始着手实现,这里列举其中用的知识点:
1,Camera 的录像的实现
2, Timer的计时
3,MediaPlayer的视频预览
因为移动端的空间有限,在视频拍摄时都会进行一些时间的限制,防止大视频上传服务器失败等种种原因,常见的微信短视频等一些终端应用都是如此。
首先我们在QtCreator中创建一个项目选择支持终端和PC的application ,在Pro中添加multimedia 重新编译,在生成的Qml页面类导入QtMultimedia 相应的版本 生声明需要的变量
property bool isCameraAvailable:QtMultimedia.availableCameras.length>0//判断当前相机是否可用
property bool isStart:false;//是否开始录像
property bool isRecord:false;//是否开始记录
property bool isLoop:true;//是否循环预览视频
property string videoName:"/mnt/sdcard/Download/vd"//视频录完后保存的名字
Rectangle{
anchors.fill:parent
visible:true
//录像的输出
VideoOutput{
anchors.fill:parent
visible:!isRecord
source:_mCamera;
}
Camera{
id:_mCamera
captureMode:Camera.CaptureVideo//设置录像模式
flash.mode:Camera.FlashRedEyeReduction
position:Camera.BackFace//设置采用后置摄像头录像
focus.focusMode:Camera.FocusAuto //自动获取焦点
focus.focusPointMode:Camera.FocusPointCenter
videoRecorder.audioEncodingMode:CameraRecorder.ConstantBitrateEncoding;
videoRecorder.audioBitRate:128000 //设置视频比特率为128000
videoRecorder.mediaContainer:"mp4"//视频录取格式为MP4
videoRecorder.outputLocation:videoName // 视频保存地址
exposure{
exposureCompensation:-1.0
exposureMode:Camera.ExposurePortrait
}
videoRecorder{
onRecorderStateChanged:{//录像状态变化的监听
console.log("onRecorderStateChanged:"+videoRecorder.recorderState);
}
onDurationChanged:{//获取录像的时长(毫秒)
tmParse(parseInt(duration/1000));
}
}
}
MediaPlayer{
id:_mPlayer
onStopped:{//需求是循环播放录像
console.log("playvideostop:")
if(isLoop){
_mPlayer.play();
}
}
}
//视频播放的输出,录像时隐藏视频播放的输出
VideoOutput{
id:_mPlayerOutput
anchors.fill:parent
visible:isRecord
}
//右边功能控制栏
Column{
anchors.right:parent.right
spacing:16
visible:isCameraAvailable
anchors.verticalCenter:parent.verticalCenter
anchors.rightMargin:18
Rectangle{
width:72;height:72;radius:width/2
color:"gray"
visible:isRecord
Text{
text:"丢弃"
anchors.fill:parent
horizontalAlignment:Text.AlignHCenter;
verticalAlignment:Text.AlignVCenter
font.pixelSize:height*0.3
color:"white"
}
MouseArea{
anchors.fill:parent
onClicked:{
isRecord=false;
isLoop=false;
_mPlayer.stop();
}
}
}
Rectangle{
width:72;height:72;radius:width/2
color:"gray";visible:!isRecord
Text{
id:_control
text:"开始";anchors.fill:parent
horizontalAlignment:Text.AlignHCenter;verticalAlignment:Text.AlignVCenter
font.pixelSize:height*0.3;color:"white"
}
MouseArea{
anchors.fill:parent
onClicked:{
if(!isStart){
console.log("getvideoname:"+videoName)
isStart=true;
_control.text="结束"
isRecord=false
_mPlayerOutput.source=_mPlayer
_mCamera.videoRecorder.record()
countDown.start();
console.log("clickisrecordvideo...")
}else{
isStart=false;
_control.text="开始"
isRecord=true
_mCamera.videoRecorder.stop()
_mPlayer.source="file://"+videoName+".mp4"
_mPlayer.play()
}
}
}
}
Rectangle{
width:72;height:72;radius:width/2
color:"gray";visible:isRecord
Text{
text:"使用"
anchors.fill:parent
horizontalAlignment:Text.AlignHCenter;
verticalAlignment:Text.AlignVCenter
font.pixelSize:height*0.3;color:"white"
}
MouseArea{
anchors.fill:parent
onClicked:{
//单击使用时根据自己的需求做相应的处理
}
}
}
}
//当前录像的时间
Rectangle{
width:160;height:160;radius:80;visible:isStart
anchors.horizontalCenter:parent.horizontalCenter
color:"#30ffffff"
Text{
id:videoTime
anchors.centerIn:parent
}
}
Text{
anchors.centerIn:parent;text:"设备不可用"
color:"whitesmoke";font.pixelSize:24
visible:!isCameraAvailable
}
}
//把毫秒转换成分秒个格式进行显示
functiontmParse(duration){
console.log("getcurrentduration:"+duration)
var min=parseInt(duration/60)
var sec=duration%60
if(sec<10){
sec="0"+sec
}
if(min<10){
min="0"+min
}
console.log("getmin:"+min+":"+sec)
videoTime.text="00:"+min+":"+sec;
}
Timer{
id:countDown
interval:10000;
running:true;
repeat:true;
onTriggered:{
_mCamera.videoRecorder.stop();
}
}
如上为简单的录像实现,在定时录像时开始在onDuration根据当前录像毫秒数进行定时结束录像,发现方法无法执行,于是添加Timer进行定时到了指定时间变停止录像。