在本文 微信小程序相機組件wx.createCameraContext()的使用模擬微信拍照之前需要看看
微信小程序-獲取用戶session_key,openid,unionid - 后端為nodejs
代碼封裝是在上文添加的。
本文知識點:
1撵溃、微信小程序相機組件wx.createCameraContext()使用
2挑势、微信小程序拍照逻翁,錄視頻實現(xiàn)
3、微信小程序上傳文件接口wx.uploadFile()的使用
4、微信小程序wx:if的使用
5掀序、nodejs上傳文件multer模塊的使用
6、camera組件使用
效果
image
在筆記本上惭婿,沒有前后置翻轉(zhuǎn)效果不恭,真機上是有的;
在微信開發(fā)工具里camera組件是透明的财饥,真機上沒問題;
在微信開發(fā)工具里上傳的視頻格式為webm换吧,真機上為mp4。
小程序代碼
1钥星、在utils下的wechat.js文件里添加代碼
/**
* 將本地資源上傳到開發(fā)者服務(wù)器沾瓦,客戶端發(fā)起一個 HTTPS POST 請求
* @param {string} url 開發(fā)者服務(wù)器 url
* @param {string} filePath 要上傳文件資源的路徑
* @param {string} name
* @param {object} formData HTTP 請求中其他額外的 form data
*/
static uploadFile(url, filePath, name, formData = { openid: "test" }) {
return new Promise((resolve, reject) => {
let opts = { url, filePath, name, formData, header: { 'Content-Type': "multipart/form-data" }, success: resolve, fail: reject };
wx.uploadFile(opts);
});
}
js
//index.js
//獲取應(yīng)用實例
let app = getApp();
let wechat = require("../../utils/wechat");
Page({
data: {
device: true,
tempImagePath: "", // 拍照的臨時圖片地址
tempThumbPath: "", // 錄制視頻的臨時縮略圖地址
tempVideoPath: "", // 錄制視頻的臨時視頻地址
camera: false,
ctx: {},
type: "takePhoto",
startRecord: false,
time: 0,
timeLoop: "",
},
onLoad() {
this.setData({
ctx: wx.createCameraContext()
})
},
// 切換相機前后置攝像頭
devicePosition() {
this.setData({
device: !this.data.device,
})
console.log("當(dāng)前相機攝像頭為:", this.data.device ? "后置" : "前置");
},
camera() {
let { ctx, type, startRecord } = this.data;
// 拍照
if (type == "takePhoto") {
console.log("拍照");
ctx.takePhoto({
quality: "normal",
success: (res) => {
// console.log(res);
this.setData({
tempImagePath: res.tempImagePath,
camera: false,
});
wechat.uploadFile("https://xx.xxxxxx.cn/api/upload", res.tempImagePath, "upload")
.then(d => {
console.log(d);
})
.catch(e => {
console.log(e);
})
},
fail: (e) => {
console.log(e);
}
})
}
// 錄視頻
else if (type == "startRecord") {
if (!startRecord) {
console.log("開始錄視頻");
this.setData({
startRecord: true
});
// 30秒倒計時
let t1 = 0;
let timeLoop = setInterval(() => {
t1++;
this.setData({
time: t1,
})
// 最長錄制30秒
if (t1 == 30) {
clearInterval(timeLoop);
this.stopRecord(ctx);
}
}, 1000);
this.setData({
timeLoop
})
// 開始錄制
ctx.startRecord({
success: (res) => {
console.log(res);
},
fail: (e) => {
console.log(e);
}
})
}
else {
this.stopRecord(ctx);
}
}
},
// 停止錄制
stopRecord(ctx) {
console.log("停止錄視頻");
clearInterval(this.data.timeLoop);
ctx.stopRecord({
success: (res) => {
this.setData({
tempThumbPath: res.tempThumbPath,
tempVideoPath: res.tempVideoPath,
camera: false,
startRecord: false,
time: 0
});
wechat.uploadFile("https://xx.xxxxxx.cn/api/upload", res.tempThumbPath, "tempThumbPath")
.then(d => {
console.log(d);
return wechat.uploadFile("https://xx.xxxxxx.cn/api/upload", res.tempVideoPath, "tempVideoPath")
})
.then(d => {
console.log(d);
})
.catch(e => {
console.log(e);
})
},
fail: (e) => {
console.log(e);
}
})
},
// 打開模擬的相機界面
open(e) {
let { type } = e.target.dataset;
console.log("開啟相機準備", type == "takePhoto" ? "拍照" : "錄視頻");
this.setData({
camera: true,
type
})
},
// 關(guān)閉模擬的相機界面
close() {
console.log("關(guān)閉相機");
this.setData({
camera: false
})
}
})
html
<view class="view">
<view class="window">
<image class="cover-9" src="{{tempImagePath}}" bindtap="img" wx:if="{{type=='takePhoto'}}"></image>
<video class="cover-9" src="{{tempVideoPath}}" poster="{{tempThumbPath}}" wx:if="{{type=='startRecord'}}"></video>
<view class="window-2">
<button bindtap="open" type="primary" data-type="takePhoto">拍照</button>
<button bindtap="open" type="primary" data-type="startRecord">錄制</button>
</view>
</view>
<camera class="camera" device-position="{{device?'back':'front'}}" wx:if="{{camera}}" flash="off">
<cover-view class="cover-1" bindtap="camera">
<cover-view class="cover-2">
<cover-view class="cover-5" wx:if="{{type=='startRecord'&&startRecord}}">{{time}}S</cover-view>
</cover-view>
</cover-view>
<cover-image class="cover-3" src="/images/xx2.png" style="width:60rpx;height:60rpx;" bindtap="close"></cover-image>
<cover-image class="cover-4" src="/images/zh.png" style="width:80rpx;height:60rpx;" bindtap="devicePosition"></cover-image>
</camera>
</view>
css
page{
height: 100%;
}
.view{
width: 100%;
height: 100%;
}
.window{
width: 100%;
height: 100%;
position: absolute;
}
.window-2{
display: flex;
flex-direction: row;
}
.camera{
width: 100%;
height: 100%;
}
.cover-1{
width: 150rpx;
height: 150rpx;
border-radius: 150rpx;
background-color: #dedcdc;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
position: absolute;
bottom: 60rpx;
left: 300rpx;
}
.cover-3{
position: absolute;
bottom: 105rpx;
left:135rpx;
}
.cover-9{
width: 728rpx;
height: 80%;
margin: 0 10rpx;
border:2rpx solid;
border-radius:5px;
}
button{
margin: 0 10rpx;
width: 100%;
}
.cover-4{
position: absolute;
top: 60rpx;
right:40rpx;
}
.cover-2{
width: 110rpx;
height: 110rpx;
border-radius: 110rpx;
background-color: #ffffff;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
color:#da2121;
font-size: 32rpx;
}
nodejs代碼
文件上傳使用multer模塊,引入multer模塊后配置好并添加一個上傳處理的路由打颤,創(chuàng)建上傳的目錄暴拄,
本文是uploads/tmp目錄
const multer = require('multer');
let path = require("path");
//上傳文件配置
const storage = multer.diskStorage({
//文件存儲位置
destination: (req, file, cb) => {
cb(null, path.resolve(__dirname, '../uploads/tmp/'));
},
//文件名
filename: (req, file, cb) => {
cb(null, `${Date.now()}_${Math.ceil(Math.random() * 1000)}_multer.${file.originalname.split('.').pop()}`);
}
});
const uploadCfg = {
storage: storage,
limits: {
//上傳文件的大小限制,單位bytes
fileSize: 1024 * 1024 * 20
}
};
router.post("/api/upload", async (req, res) => {
let upload = multer(uploadCfg).any();
upload(req, res, async (err) => {
if (err) {
res.json({ path: `//uploads/tmp/${uploadFile.filename}` });
console.log(err);
return;
};
console.log(req.files);
let uploadFile = req.files[0];
res.json({ path: `//uploads/tmp/${uploadFile.filename}` });
});
})
后端打印
image
上傳的文件夾
image
素材
向下箭頭:https://img-blog.csdn.net/20180226111545178
翻轉(zhuǎn)圖片:https://img-blog.csdn.net/20180226111559273
參考地址:
https://mp.weixin.qq.com/debug/wxadoc/dev/component/camera.html
https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-camera.html