? ? ? ? 在使用QML做移動端開發(fā)時狮含,我們總是會接觸到多媒體的開發(fā)剩晴,尤其在當下這個流媒體時代晶乔,拍小視頻已經(jīng)成為了一種風尚珍坊,記錄每個的生活軌跡,四季變化正罢。
? ? ? ? ?這里通過QML實現(xiàn)簡單的錄像預覽阵漏,錄像界面如下:
? ? ? ? 左邊顯示錄像和錄像的時間,右邊功能控制區(qū)域翻具,單擊開始時開始計時履怯,開始按鈕變成結(jié)束,單擊結(jié)束時界面如下:
? ? ? ? ?進入視頻預覽裆泳,右邊功能區(qū)叹洲,單擊丟棄則進入視頻初始頁面,單擊使用則根據(jù)個人需求做相應處理工禾,功能基本如上运提,接下來開始著手實現(xiàn),這里列舉其中用的知識點:
1闻葵,Camera 的錄像的實現(xiàn)
2, Timer的計時
3民泵,MediaPlayer的視頻預覽
? ? ? ? 因為移動端的空間有限,在視頻拍攝時都會進行一些時間的限制槽畔,防止大視頻上傳服務器失敗等種種原因栈妆,常見的微信短視頻等一些終端應用都是如此。
? ? ? ? 首先我們在QtCreator中創(chuàng)建一個項目選擇支持終端和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;//是否循環(huán)預覽視頻
property string videoName:"/mnt/sdcard/Download/vd"http://視頻錄完后保存的名字
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"http://視頻錄取格式為MP4
? ?videoRecorder.outputLocation:videoName // 視頻保存地址
? exposure{
? ? ? exposureCompensation:-1.0
? ? ? exposureMode:Camera.ExposurePortrait
? }?
videoRecorder{
? ? ? ? ?onRecorderStateChanged:{//錄像狀態(tài)變化的監(jiān)聽
? ? ? ? ? ? ? ? console.log("onRecorderStateChanged:"+videoRecorder.recorderState);
? }
? ? onDurationChanged:{//獲取錄像的時長(毫秒)
? ? ? ?tmParse(parseInt(duration/1000));
? }
}
}
MediaPlayer{
? ? ? id:_mPlayer
? ? ? onStopped:{//需求是循環(huán)播放錄像
? ? ? 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="結(jié)束"
? ? ? ? ? ? ? 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:{
? ? ? ? ?//單擊使用時根據(jù)自己的需求做相應的處理
? ? ? ? ?}
? ? }
?}
}
//當前錄像的時間
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
? }
}
//把毫秒轉(zhuǎn)換成分秒個格式進行顯示
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();
? }
}
如上為簡單的錄像實現(xiàn)早直,在定時錄像時開始在onDuration根據(jù)當前錄像毫秒數(shù)進行定時結(jié)束錄像铅檩,發(fā)現(xiàn)方法無法執(zhí)行,于是添加Timer進行定時到了指定時間變停止錄像莽鸿。