需求背景
当客户发货或者收货时 需要上传开箱或者封箱视频,直接选择相册视频上传速度太慢,现在随便一个视频都是几百M的,流量费很贵,所以就选择使用 直播推流的方式 实现视频上传。
app开发,推荐使用nvue做直播,比使用vue的优势有:文章来源:https://www.toymoban.com/news/detail-503266.html
- nvue也可一套代码编译多端。
- nvue的cover-view比vue的cover-view更强大,在视频上绘制元素更容易。如果只考虑App端的话,不用cover-view,任意组件都可以覆盖live-pusher组件,因为nvue没有层级问题。
- 若需要视频内嵌在swiper里上下滑动(类抖音、映客首页模式),App端只有nvue才能实现 当然nvue相比vue的坏处是css写法受限,如果只开发微信小程序,不考虑App,那么使用vue页面也是一样的。
- 创建 live-pusher 上下文 livePusherContext 对象
onReady() {
// 注意:需要在onReady中 或 onLoad 延时
this.context = uni.createLivePusherContext('livePusher', this);
//获取手机信息,并设置高度和宽度
try {
const res = uni.getSystemInfoSync();
this.width = res.windowWidth;
this.height = res.windowHeight;
} catch (e) {
throw Error(e)
}
},
- 获取请求url宽高自适应全屏 注:安卓手机需要主动启动摄像头
onShow() {
//开启预览
uni.getStorage({
key: 'livepushurl',
success:(res) =>{
const { url,id} = res.data
this.livepushurl= url
this.id = id
}
});
if(systemInfo.platform == 'android'){
this.startPreview();
}
this.startTime()
},
- onHide 处理 当用户切屏出去时 live-pusher会有bug 黑屏等问题,需要进行处理,当前处理3秒以内不保存页面后退。3秒以上进行保存页面后台
onHide() {
if(!this.showTime){
if (this.count <= 3) {
var page = getCurrentPages();
var prevPage = page[page.length - 2];
prevPage.$vm.closePusher(this.id);
uni.navigateBack({
delta: 1,
});
}else{
this.stop()
var page = getCurrentPages();
var prevPage = page[page.length - 2];
prevPage.$vm.finishPusher(this.id);
uni.navigateBack({
delta: 1,
});
}
}
},
- HTML 代码块 nvue 设置class样式不生效 使用style 行内样式 (width height)
<view class="content">
<live-pusher
id="livePusher"
ref="livePusher"
:style="{width: width + 'px',height:height + 'px'}"
:url="livepushurl"
:mode="mode"
:muted="false"
:enable-camera="true"
:auto-focus="true"
:beauty="beauty"
:whiteness="whiteness"
aspect="9:16"
enable-mic="true"
device-position="back"
@statechange="statechange"
@netstatus="netstatus"
@error="error">
</live-pusher>
<view class="timekeeping" style="width: 200rpx;" :style="{ top: iStatusBarHeight + 'px'}">
<text class="timekeeping-time" style="color: #FFFFFF;">{{time}}</text>
</view>
<view class="pusher-handle">
<view class="pusher-handle-btn" @click="switchCamera">
<image style="width: 68rpx;height: 68rpx;" src="../../static/images/live-pusher-switch.png" resize="cover"></image>
</view>
<view class="pusher-handle-btn pusher-handle-center" @click="showConfirmModal">
<image style="width: 112rpx;height: 112rpx;" src="../../static/images/live-pusher-finish.png" resize="cover"></image>
</view>
<view class="pusher-handle-btn" @click="canceLlivePusher">
<image style="width: 68rpx;height: 68rpx;" src="../../static/images/live-pusher-close.png" resize="cover"></image>
</view>
</view>
<view class="countdown" v-if="showTime">
<text class="countdown-text">{{count}}</text>
</view>
</view>
- 完成代码
let systemInfo = uni.getSystemInfoSync();
export default {
data() {
return {
width: '350px',
height: '1500px',
mode: 'FHD', //流视频模式,可取值:SD(标清), HD(高清), FHD(超清)
beauty: 1, //美颜,取值范围 0-9(iOS取值范围为1) ,0 表示关闭
whiteness: 2, // 美白,取值范围 0-9(iOS取值范围为1) ,0 表示关闭
context: [],
livepushurl: '',
url: '',
showTime: true,
confirmContent: '是否确认上传当前录制?',
cancleContent: '是否确认退出当前录制?',
showConfirm: false,
showCancel: false,
id: null,
time: '00:00:00',
iStatusBarHeight: 32,
count: 0,
};
},
onReady() {
// 注意:需要在onReady中 或 onLoad 延时
this.context = uni.createLivePusherContext('livePusher', this);
//获取手机信息,并设置高度和宽度
try {
const res = uni.getSystemInfoSync();
this.width = res.windowWidth;
this.height = res.windowHeight;
} catch (e) {
throw Error(e)
}
},
onLoad() {
},
onShow() {
//开启预览
uni.getStorage({
key: 'livepushurl',
success:(res) =>{
const { url,id} = res.data
this.livepushurl= url
this.id = id
}
});
if(systemInfo.platform == 'android'){
this.startPreview();
}
this.startTime()
},
onHide() {
if(!this.showTime){
if (this.count <= 3) {
var page = getCurrentPages();
var prevPage = page[page.length - 2];
prevPage.$vm.closePusher(this.id);
uni.navigateBack({
delta: 1,
});
}else{
this.stop()
var page = getCurrentPages();
var prevPage = page[page.length - 2];
prevPage.$vm.finishPusher(this.id);
uni.navigateBack({
delta: 1,
});
}
}
},
methods: {
async geturl() {
try {
const res = await getUrl({
order_id: this.order_id,
type: this.type
})
this.url = res.push.rtmp
this.id = res.id
this.startTime()
} catch (e) {
}
},
startTime() {
const TIME_COUNT = 5;
if (!this.timer) {
this.count = TIME_COUNT;
this.timer = setInterval(() => {
if (this.count > 0 && this.count <= TIME_COUNT) {
this.count--;
} else {
this.showTime = false;
clearInterval(this.timer)
this.timer = null;
this.start()
if(systemInfo.platform == 'ios'){
this.switchCamera()
}
this.timekeeping()
}
}, 1000)
}
},
timekeeping() {
// var count = 0;
if (!this.timerInter) {
this.timerInter = setInterval(() => {
var h = parseInt(this.count / 60 / 60);
var m = parseInt(this.count / 60) % 60;
var s = parseInt(this.count ) % 60;
h = h < 10 ? '0' + h : h;
m = m < 10 ? '0' + m : m;
s = s < 10 ? '0' + s : s;
this.time = h + ':' + m + ':' + s ;
this.count += 1;
}, 1000)
}
},
statechange(e) {
console.log('状态变化事件:' + JSON.stringify(e));
},
netstatus(e) {
console.log('网络状态通知事件:' + JSON.stringify(e));
},
error(e) {
console.log('渲染错误事件:' + JSON.stringify(e));
},
start() {
this.context.start({
success: a => {
console.log('开始推流:' + JSON.stringify(a));
},
error: err => {
console.log(err)
}
});
},
snapshot() {
this.context.snapshot({
success: e => {
console.log('快照:' + JSON.stringify(e));
}
});
},
resume() {
this.context.resume({
success: a => {
console.log('恢复推流:' + JSON.stringify(a));
}
});
},
pause() {
this.context.pause({
success: a => {
console.log('暂停推流:' + JSON.stringify(a));
}
});
},
stop() {
this.context.stop({
success: a => {
console.log('停止推流:' + JSON.stringify(a));
}
});
},
switchCamera() {
this.context.switchCamera({
success: a => {
console.log('切换前后摄像头:' + JSON.stringify(a));
}
});
},
startPreview() {
this.context.startPreview({
success: a => {
console.log('开启摄像头预览:' + JSON.stringify(a));
}
});
},
stopPreview() {
this.context.stopPreview({
success: a => {
console.log('关闭摄像头预览:' + JSON.stringify(a));
}
});
},
showConfirmModal() {
if (this.count <= 3) {
uni.showToast({
title: '上传视频不能低于3秒',
icon: "none",
duration: 2000,
});
return
}
uni.showModal({
title: '提示',
content: '是否确认上传当前录制?',
success: (res)=> {
if (res.confirm) {
clearInterval(this.timerInter);
uni.showLoading({
title: '提交中'
})
setTimeout(()=>{
uni.hideLoading()
this.stop()
var page = getCurrentPages();
var prevPage = page[page.length - 2];
prevPage.$vm.finishPusher(this.id);
uni.navigateBack({
delta: 1,
});
},2000)
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
// this.showConfirm = true
},
canceLlivePusher(){
uni.showModal({
title: '提示',
content: '是否确认退出当前录制?',
success: (res)=> {
if (res.confirm) {
this.stop()
var page = getCurrentPages();
var prevPage = page[page.length - 2];
prevPage.$vm.closePusher(this.id);
uni.navigateBack({
delta: 1,
});
} else if (res.cancel) {
console.log('用户点击取消');
}
},
})
}
}
};
- 结尾
参数说明、回调方法可参考 文档文章来源地址https://www.toymoban.com/news/detail-503266.html
到了这里,关于uni app 使用live-pusher录制视频的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!