liver-pusher,.nvue,css,利用livePusher完成在首页加载时拍照并回显到页面,没有使用RTMP协议。

文章讲述了在.nvue文件中使用live-pusher组件来实现摄像头功能遇到的问题,包括live-pusher只能在.nvue中触发,不支持样式如flex和相对定位,以及仅适用于微信小程序。作者提供了一段代码示例,展示如何在页面加载时启动摄像头,并处理拍照、回显和恢复操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、live-pusher只能在.nvue中触发。

2、.nvue中无法使用flex,相对定位等样式。

3、live-pusher只支持微信小程序

  有这么一个需求,在首次进页面的时候就在指定区域调用摄像头,点击拍照,回显到页面,点击恢复就可以在次调用到摄像头。

   一、实现起来有点困难,之前的同事使用<upload></upload>实现的,但是首次进入页面的时候无法直接使用相机,于是使用<live-pusher></live-pusher>

   二、在.nvue中无法直接使用display:flex,无法直接给<view><view>中的元素设置字体颜色border等,使用<text></text>代替

废话不多说直接上代码,在.nvue文件中添加如下代码,在移动端调试(h5等不支持)

<template>
	<view class='outer'>
		<view class='fixToHead'>
		</view>
		<view class='fristLine' @click="back">
			<image class="imageBox" src="../../../static/nutImage/back.png" mode="aspectFit">
			</image>
			<text class="firstText">任务 {{taskInfo.taskId}}</text>
		</view>
		<view>
			<view v-if='status'>
				<live-pusher id='livePusher' ref="livePusher" class='livePusher' url="" mode="FHD" :muted="true" :enable-camera="true" :auto-focus="false"
				 :beauty="0" whiteness="0" aspect="8:3" @statechange="statechange" @netstatus="netstatus" @error="error"
				 device-position='back' :zoom='true' orientation="horizontal"></live-pusher>
			</view>
			<view v-if='!status'>
				<image class='livePusher' :src="imgStr" title="加载中...请稍等" alt="加载中...请稍等"></image>
			</view>
		</view>
		<view class='blackBack'>
			<view class='secondBlock'>
				<view class="secondHead" v-if="stepIndex!==0">
					<text class='secondStep'>步骤{{stepIndex}}</text>
					<text class='secondProgress'>{{stepIndex}}/{{step.length?step.length:0}}</text>
				</view>
			
				<view class='thirdTitle' v-if="stepIndex!==0">
					<text class='thridBody'>{{step[stepIndex - 1 ].ancestor?step[stepIndex - 1 ].ancestor:null }}({{step[stepIndex - 1 ].checkItem}})</text>
					<text class='thridBody'>{{step[stepIndex - 1 ].description }}</text>
				</view>
				<view class='fourthTitle' v-if="stepImages.length>0">
					<image class='fourthImage' v-for="(item,index) in stepImages" :src="stepImages[index]" mode="aspectFit" @click="clickImg(stepImages[index])"></image>
				</view>
			</view>
		</view>

		<view class='stepBtn'>
			<text class='grayBtn lastBtn' @click="stepPre()">上一步</text>
			<text class='pretyBtn photoBtn' @click="snapshot" v-if='status'>快照</text>
			<text class='grayBtn photoBtn' @click="resume" v-if='!status'>恢复</text>
			<text class='pretyBtn nextBtn' v-if="stepIndex!==step.length" @click="stepNext()">下一步</text>
			<text class='pretyBtn nextBtn' v-if="stepIndex===step.length" @click="stepNext('end')">结束</text>
		</view>
	</view>
</template>

<script>
	const NET = require("../../../utils/request");
	const API = require("../../../config/api");
	export default {
		data() {
			return {
				fil: true,
				imgList: [""],
				showBorder: true,
				context: null,
				form: {},
				status: true,
				imgStr: '',
				taskInfo: {},
				check: [],
				ance: [],
				checkList: [],
				stepImages: [],
				taskCircuitRecordList: [],
				step: [],
				stepIndex: 0,
				num: 0,
				action: API.WX_API_BASE + 'blade-resource/oss/endpoint/put-file',
				TypeList: [],
				logList1: [],
				imgStr: '',
				fil: true,
				imgList: [""],
				showBorder: true,
				context: null,
				form: {},
				showPusher: true,
				quickphoto: '',
			};
		},
		onLoad(op) {
			this.taskId = op.taskId
			this.taskListInfo();
		},
		mounted() {
			this.startPreview();
		},
		onShow() {
			this.context = uni.createLivePusherContext("livePusher", this);
			this.startPreview();
			plus.navigator.setStatusBarStyle("dark"); //只支持dark和light
		},
		onReady() {
			// // 注意:需要在onReady中 或 onLoad 延时
			// this.context = uni.createLivePusherContext("livePusher", this);
			// this.startPreview();
			// plus.navigator.setStatusBarStyle("dark"); //只支持dark和light
		},
		methods: {
			promptMsg(context) {
				uni.showModal({
					title: "提示",
					content: context,
					showCancel: false
				})
			},
			resume() {
				this.imgStr = '';
				this.status = true;
				this.context = uni.createLivePusherContext("livePusher", this);
				this.startPreview();
			},
			// 拍照事件
			snapshot: function(val) {
				this.context.snapshot({
					success: (e) => {
						this.getMinImage(e.message.tempImagePath)
						this.status = false
					},
				});
			},
			// 开启摄像头
			startPreview() {
				var that = this;
				this.context.startPreview({
					success: (a) => {
						that.Timer = setInterval(function() {}, 5000);
					},
				});
			},
			// 使用plus.zip.compressImage压缩图片并转换成base64
			getMinImage(imgPath) {
				plus.zip.compressImage({
						src: imgPath,
						dst: imgPath,
						overwrite: true,
						quality: 40
					},
					zipRes => {
						setTimeout(() => {
							var reader = new plus.io.FileReader();
							reader.onloadend = res => {
								var speech = res.target.result; //base64图片
								this.imgList.push(speech);
								this.form.imgStr = speech
								NET.request(API.putFile, {
										base64: speech,
									},
									'POST').then(res => {
										if(res.code !== 200){
											this.promptMsg('图片上传失败,请联系管理员')
										}
										this.imgStr = res.data.link
										console.log(res);
								})
							};
							reader.readAsDataURL(plus.io.convertLocalFileSystemURL(zipRes.target));
						}, 100);
					},
					function(error) {
						console.log('Compress error!', error);
					}
				);
			},

			clickImg(val) {
				wx.previewImage({
					urls: [val], //需要预览的图片http链接列表,多张的时候,url直接写在后面就行了
					current: '', // 当前显示图片的http链接,默认是第一个
					success: function(res) {},
					fail: function(res) {},
					complete: function(res) {},
				})
			},

			back() {
				uni.navigateBack({
					delta: 1
				})
			},

			imgFinish(val) {
				this.imgList.push(val.data.link)
				this.imgStr = this.imgList.toString()
			},

			removeImg(val) {
				this.imgList.splice(val, 1);
				this.imgStr = this.imgList.toString()
				console.log(111, this.imgStr)
			},

			stepPre() {
				if (this.stepIndex < 2) {
					return
				}
				this.stepIndex--;
				this.stepImages = this.step[this.stepIndex - 1].checkItemStepImage.split(",")
				// this.$refs.uUpload.clear()
				this.imgStr = '';
				this.logList1 = [];
				this.imgList = []
			},

			stepNext(val) {
				if (this.imgStr === '') {
					this.promptMsg('请拍摄巡检图片')
					return
				} else {
					NET.request(API.artificialCognition, {
							imgUrl: this.imgStr,
							taskId: this.taskId,
							stepId: this.step[this.stepIndex - 1].id
						},
						'post').then(res => {
						if (val === 'end') {
							this.submit()
						} else {
							// this.promptMsg('巡检图片已上传')
						}
						let that = this;

						if (that.stepIndex >= that.step.length) {
							return
						}
						that.imgStr = '';
						that.logList1 = [];
						that.imgList = []
						that.stepIndex++;
						that.stepImages = that.step[that.stepIndex - 1].checkItemStepImage.split(",")
						that.status = true
					})
				}
			},

			submit() {
				NET.request(API.submitTask, {
						id: this.taskId,
						circuitPlanId: this.taskInfo.circuitPlanId
					},
					'post').then(res => {
					this.promptMsg('任务完成')
					let that = this;
					setTimeout(() => {
						that.back()
					}, 1000)
				})
			},

			clickImg(val) {
				wx.previewImage({
					urls: [val], //需要预览的图片http链接列表,多张的时候,url直接写在后面就行了
					current: '', // 当前显示图片的http链接,默认是第一个
					success: function(res) {},
					fail: function(res) {},
					complete: function(res) {},
				})
			},

			taskListStep() {
				NET.request(API.taskListStep, {
						id: this.taskId,
						circuitPlanId: this.taskInfo.circuitPlanId
					},
					'get').then(res => {
					this.step = res.data
					if (this.step.length > 0) {
						this.stepIndex = 1,
							this.stepImages = this.step[this.stepIndex - 1].checkItemStepImage.split(",")
					}
				})
			},
			taskListInfo() {
				NET.request(API.taskDetail, {
						id: this.taskId
					},
					'get').then(res => {
					this.taskInfo = res.data;
					this.taskListStep();
				})
			},
		},
	};
</script>

<style>
	.outer {
		background-color: white;
		/* height: 740px; */
	}
	.block {
		height: 26px;
		width: 500px;
		background-color: #989898;
		color: #989898;
	}
	.livePusher{
		height:340px;
	}

	.livePush {
		border-radius: 10px;
		width: 300px;
		height: 300px;
	}

	.test {
		flex-direction: row;
	}

	/* ------------- */
	.fixToHead {
		position: fixed;
		top: 0;
		z-index: 9999;
		height: 26px;
		width: 500px;
		background-color: #989898;
		color: #989898;
		/* height: 26px; */
	}

	.fristLine {
		margin-top: 26px;
		height: 35px;
		flex-direction: row;
		align-items: center;
		background-color:white;
	}

	.scrollView {
		width: 300px;
	}

	.imageBox {
		margin-left: 18px;
		width: 16px;
		height: 16px;
	}

	.firstText {
		margin-left: 85px;
		font-weight: bold;
		font-size: 15px;
	}

	.blackBack{
		height:700px;
		maigin-bottom:60px;
		background-color: #000000;
	}
	.secondBlock {
		padding: 20px 8px;
		width: auto;
		background-color: white;
		border: 10px;
	}

	.secondHead {
		flex-direction: row;
		align-items: center;
	}

	.secondStep {
		font-weight: bold;
		font-size: 15px;
		margin-right: 5px;
	}

	.secondProgress {
		font-size: 10px;
		background-color: #e4eeff;
		color: #3c6ba9;
		border-radius: 30px;
		padding: 2px;
	}

	.thirdTitle {
		margin-top: 9px;
	}

	.thridBody {
		font-size: 13px;
		color: #222222;
	}

	.fourthTitle {
		margin-top: 8px;
	}

	.fourthImage {
		width: 79px;
		height: 78px;
	}

	.videoBox {
		position: relative;
		margin: 0px 15px;
		background-color: white;
		border-radius: 10px;
		padding: 10px;
	}

	.grayBtn {
		color: #a9a9a9;
		background-color: #ececec;
		border-radius: 4px;
		border-width: 1px;
		border-color: #a9a9a9;
		padding:10px;
	}
	.pretyBtn{
		color: white;
		background-color: #3167f6;
		border-radius: 4px;
		border-width: 1px;
		border-color: #3167f6;
		padding:10px;
	}
	.lastBtn{
		margin-left: 50px;
	}
	.photoBtn{
		margin-left: 30px;
	}
	.nextBtn{
		margin-left: 30px;
	}

	.copyImage{
		border-radius: 10px;
	}

	.stepBtn{
		width:800px;
		flex-direction: row;
		align-items: center;
	    position:fixed;
		bottom:0;
		background-color:white;
        height:60px;
	}
</style>

如发现不太正确的请留言指正,感谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每天吃饭的羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值