小程序短視頻項目———上傳短視頻業務
阿新 • • 發佈:2018-10-05
sta quest upd cati let oop back tip media
一、用戶選擇視頻
1、微信選中視頻接口
wx.chooseVideo(Object object)
拍攝視頻或從手機相冊中選視頻。
參數
Object object
屬性 | 類型 | 默認值 | 是否必填 | 說明 | 支持版本 |
---|---|---|---|---|---|
sourceType | Array.<string> | [‘album‘, ‘camera‘] | 否 | 視頻選擇的來源 | |
compressed | boolean | true | 否 | 是否壓縮所選擇的視頻文件 | >= 1.6.0 |
maxDuration | number | 60 | 否 | 拍攝視頻最長拍攝時間,單位秒 | |
camera | string | ‘back‘ | 否 | 默認拉起的是前置或者後置攝像頭。部分 Android 手機下由於系統 ROM 不支持無法生效 | |
success | function | 否 | 接口調用成功的回調函數 | ||
fail | function | 否 | 接口調用失敗的回調函數 | ||
complete | function | 否 | 接口調用結束的回調函數(調用成功、失敗都會執行) |
object.sourceType 的合法值
值 | 說明 |
---|---|
album | 從相冊選擇視頻 |
camera | 使用相機拍攝視頻 |
object.camera 的合法值
值 | 說明 |
---|---|
back | 默認拉起後置攝像頭 |
front | 默認拉起前置攝像頭 |
object.success 回調函數
參數
Object res
屬性 | 類型 | 說明 | 支持版本 |
---|---|---|---|
tempFilePath | string | 選定視頻的臨時文件路徑 | |
duration | number | 選定視頻的時間長度 | |
size | number | 選定視頻的數據量大小 | |
height | number | 返回選定視頻的高度 | |
width | number | 返回選定視頻的寬度 |
示例代碼
wx.chooseVideo({ sourceType: [‘album‘,‘camera‘], maxDuration: 60, camera: ‘back‘, success(res) { console.log(res.tempFilePath) } })
2、mine.js文件上傳視頻事件綁定uploadVideo事件編寫(註:此步驟暫時只包含選中視頻並上傳到臨時路徑)
uploadVideo: function(){ var me = this; wx.chooseVideo({ sourceType: [‘album‘], success(res) { console.log(res); var duration = res.duration; var tmpheight = res.height; var tmpwidth = res.width; var tmpVideoUrl = res.tempFilePath; var tmpCoverUrl = res.thumbTempFilePath; if(duration > 11){ wx.showToast({ title: ‘視頻長度不能超過10秒...‘, icon: "none", duration: 2500 }) } else if (duration < 1){ wx.showToast({ title: ‘視頻長度不能小於1秒...‘, icon: "none", duration: 2500 }) }else{ //TODO 打開選擇bgm的頁面 } } }) }
二、選擇背景音樂頁面
1、
chooseBgm.wxml
<view> <form bindsubmit=‘upload‘> <radio-group name="bgmId"> <block wx:for="{{bgmList}}"> <view class=‘container‘> <audio name="{{item.name}}" author="{{item.author}}" src="{{serverUrl}}{{item.path}}" style=‘width:300px‘ id="myAudio" controls loop></audio> <radio style=‘margin-top:20px;‘ value=‘{{item.id}}‘></radio> </view> </block> </radio-group> <view class="inputView"> <label class="loginLabel">視頻描述:</label> <input name="desc" class="inputText" placeholder="說點什麽吧" /> </view> <!-- 提交 --> <button class="submitBtn" type="primary" form-type=‘submit‘>上傳視頻</button> <button class="gobackBtn" type="warn" form-type=‘reset‘>重置</button> </form> </view>
chooseBgm.wxss
page { height: 100%; } .container { display: flex; margin-top: 20rpx; justify-content: space-around; } .submitBtn { width: 80%; margin-top: 15px; } .gobackBtn { width: 80%; margin-top: 15px; } .loginLabel { color: gray; font-size: 15px; } .inputText { float: right; text-align: right; margin-right: 22px; margin-top: 11px; font-size: 15px; } .inputView { padding: 5px; background-color: white; line-height: 45px; border: solid 1px whitesmoke; }
2、微信音頻接口
audio
註意:1.6.0 版本開始,該組件不再維護。建議使用能力更強的 wx.createInnerAudioContext 接口
音頻。
屬性名 | 類型 | 默認值 | 說明 |
---|---|---|---|
id | String | audio 組件的唯一標識符 | |
src | String | 要播放音頻的資源地址 | |
loop | Boolean | false | 是否循環播放 |
controls | Boolean | false | 是否顯示默認控件 |
poster | String | 默認控件上的音頻封面的圖片資源地址,如果 controls 屬性值為 false 則設置 poster 無效 | |
name | String | 未知音頻 | 默認控件上的音頻名字,如果 controls 屬性值為 false 則設置 name 無效 |
author | String | 未知作者 | 默認控件上的作者名字,如果 controls 屬性值為 false 則設置 author 無效 |
binderror | EventHandle | 當發生錯誤時觸發 error 事件,detail = {errMsg: MediaError.code} | |
bindplay | EventHandle | 當開始/繼續播放時觸發play事件 | |
bindpause | EventHandle | 當暫停播放時觸發 pause 事件 | |
bindtimeupdate | EventHandle | 當播放進度改變時觸發 timeupdate 事件,detail = {currentTime, duration} | |
bindended | EventHandle | 當播放到末尾時觸發 ended 事件 |
MediaError.code
返回錯誤碼 | 描述 |
---|---|
1 | 獲取資源被用戶禁止 |
2 | 網絡錯誤 |
3 | 解碼錯誤 |
4 | 不合適資源 |
三、開發後臺bgm列表接口
四、bgm頁面聯調獲取背景音樂列表
chooseBgm.wxml
<view> <form bindsubmit=‘upload‘> <radio-group name="bgmId"> <block wx:for="{{bgmList}}"> <view class=‘container‘> <audio name="{{item.name}}" author="{{item.author}}" src="{{serverUrl}}{{item.path}}" style=‘width:300px‘ id="myAudio" controls loop></audio> <radio style=‘margin-top:20px;‘ value=‘{{item.id}}‘></radio> </view> </block> </radio-group> <view class="inputView"> <label class="loginLabel">視頻描述:</label> <input name="desc" class="inputText" placeholder="說點什麽吧" /> </view> <!-- 提交 --> <button class="submitBtn" type="primary" form-type=‘submit‘>上傳視頻</button> <button class="gobackBtn" type="warn" form-type=‘reset‘>重置</button> </form> </view>
chooseBgm.js
const app = getApp() Page({ data: { bgmList: [], serverUrl: "", poster: ‘http://y.gtimg.cn/music/photo_new/T002R300x300M000003rsKF44GyaSk.jpg?max_age=2592000‘, name: ‘此時此刻‘, author: ‘許巍‘, src: ‘http://ws.stream.qqmusic.qq.com/M500001VfvsJ21xFqb.mp3?guid=ffffffff82def4af4b12b3cd9337d5e7&uin=346897220&vkey=6292F51E1E384E06DCBDC9AB7C49FD713D632D313AC4858BACB8DDD29067D3C601481D36E62053BF8DFEAF74C0A5CCFADD6471160CAF3E6A&fromtag=46‘, }, onLoad: function (params) { var me = this; wx.showLoading({ title: ‘請等待...‘, }); var serverUrl = app.serverUrl; // 調用後端 wx.request({ url: serverUrl + ‘/bgm/list‘, method: "POST", header: { ‘content-type‘: ‘application/json‘ // 默認值 }, success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { var bgmList = res.data.data; me.setData({ bgmList: bgmList, serverUrl: serverUrl }); } } }) } })
五、開發上傳短視頻接口
package com.imooc.controller; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import org.apache.commons.lang3.StringUtils; import org.apache.tomcat.util.http.fileupload.IOUtils; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import com.imooc.pojo.Users; import com.imooc.utils.IMoocJSONResult; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @RestController @Api(value="視頻相關業務的接口", tags= {"視頻相關業務的controller"}) @RequestMapping("/video") public class VideoController { @ApiOperation(value="用戶上傳視頻", notes="用戶上傳視頻的接口") @ApiImplicitParams({ @ApiImplicitParam(name="userId", value="用戶id", required=true, dataType="String", paramType="form"), @ApiImplicitParam(name="bgmId", value="背景音樂id", required=false, dataType="String", paramType="form"), @ApiImplicitParam(name="videoSeconds", value="背景音樂播放長度", required=true, dataType="String", paramType="form"), @ApiImplicitParam(name="videoWidth", value="視頻寬度", required=true, dataType="String", paramType="form"), @ApiImplicitParam(name="videoHeight", value="視頻高度", required=true, dataType="String", paramType="form"), @ApiImplicitParam(name="desc", value="視頻描述", required=false, dataType="String", paramType="form") }) @PostMapping(value="/upload", headers="content-type=multipart/form-data") public IMoocJSONResult upload(String userId, String bgmId, double videoSeconds, int videoWidth, int videoHeight, String desc, @ApiParam(value="短視頻", required=true) MultipartFile file) throws Exception { //Alt + shirt + R //文件保存的空間 String fileSpace = "D:/imooc_videos_dev"; //保存到數據庫的相對路徑 String uploadPathDB = "/" + userId + "/video" ; FileOutputStream fileOutputStream = null; InputStream inputStream = null; try { if(file != null ) { String fileName = file.getOriginalFilename(); if(StringUtils.isNoneBlank(fileName)) { //文件上傳的最終路徑 String finalVideoPath = fileSpace + uploadPathDB + "/" + fileName; //設置數據庫保存的路徑 uploadPathDB += ("/" + fileName); File outFile = new File(finalVideoPath); if(outFile.getParentFile() != null || !outFile.getParentFile().isDirectory()) { //創建父文件夾 outFile.getParentFile().mkdirs(); } fileOutputStream = new FileOutputStream(outFile); inputStream = file.getInputStream(); IOUtils.copy(inputStream, fileOutputStream); } } } catch (Exception e) { e.printStackTrace(); }finally { if(fileOutputStream != null) { fileOutputStream.flush(); fileOutputStream.close(); } } return IMoocJSONResult.ok(); } }
六、視頻臨時參數傳入到下一個頁面
首先在mine.js文件上的uploadVideo事件上補充頁面跳轉到chooseBgm.wxml
//打開選擇bgm的頁面 wx.navigateTo({ url: ‘../chooseBgm/chooseBgm?duration=‘ + duration + "&tmpHeight=" + tmpHeight + "&tmpWidth=" + tmpWidth + "&tmpVideoUrl=" + tmpVideoUrl + "&tmpCoverUrl=" + tmpCoverUrl , })
然後在chooseBgm.js文件上的初加載事件onLoad事件上通過參數param接受,VideoParams是在一開始就設置的。
var me = this; console.log(params); me.setData({ videoParams: params });
整個上傳視頻事件upLoad事件
upload: function(e) { var me = this; var bgmId = e.detail.value.bgmId; var desc = e.detail.value.desc; console.log("bgmId:" + bgmId); console.log("desc:" + desc); var duration = me.data.videoParams.duration; var tmpheight = me.data.videoParams.tmpHeight; var tmpwidth = me.data.videoParams.tmpWidth; var tmpVideoUrl = me.data.videoParams.tmpVideoUrl; var tmpCoverUrl = me.data.videoParams.tmpCoverUrl; //上傳短視頻 wx.showLoading({ title: ‘Loading...‘, }) var serverUrl = app.serverUrl; wx.uploadFile({ url: serverUrl + ‘/video/upload‘, formData: { userId: app.userInfo.id, bgmId: bgmId, desc: desc, videoSeconds: duration, videoHeight: tmpheight, videoWidth: tmpwidth }, filePath: tmpVideoUrl, name: ‘file‘, header: { ‘content-type‘: ‘application/json‘ // 默認值 }, success(res) { // var data = JSON.parse(res.data); console.log(res); wx.hideLoading(); if (data.status == 200) { wx.showToast({ title: ‘上傳成功!~~‘, icon: "success" }); } } }) }
小程序短視頻項目———上傳短視頻業務