<view class="main_info">
<view class="top">
<live-pusher id='livePusher' ref="livePusher"
class="livePusher" :url="socketInfo.rtmp" :muted="true" :enable-mic="isRealTime" :enable-camera="false"
@error = "error"></live-pusher>
<view class="inp_itm">
<view class="left">
音量大小
<text class="tips">可输入音量大小0-100</text>
</view>
<view class="right">
<u-number-box bgColor="#fff" :min="0" :max="100" v-model="volume">
<view slot="minus" class="minus">
<u-icon name="minus" size="12"></u-icon>
</view>
<view slot="plus" class="plus">
<u-icon name="plus" size="12"></u-icon>
</view>
</u-number-box>
</view>
</view>
<!-- 喊话时长 -->
<view class="duration_shouting">
喊话时长:{{formatTime(timesNum)}}
</view>
<view class="play_btn">
<u-button class="custom-style" @click="realTime" :text="!isRealTime? '开始':'结束'"></u-button>
</view>
</view>
<u-toast ref="uToast"></u-toast>
</view>
</template>
<script>
import {getAction,postAction} from "@/api/mamage.js"
import {formatTime} from "@/util/validate.js"
export default {
data() {
return {
towerInfo: null, // 监测塔相关信息
objurl: {
webSocktInfo: `/hytec/saas/app/talk/start`,
stop: `/hytec/saas/app/talk/stop`, // 停止喊话
heart:`/hytec/saas/web/talk/heart` // 心跳
},
volume: 70, // 音量
socketInfo: {}, // socketInfo
isRealTime: false, // 是否正在实时喊话
timesNum: 0, // 喊话秒数
timesTimer: null ,// 喊话定时器
timer: null ,// 心跳定时器
context: null
}
},
onReady(){
},
onLoad(option) {
// 接收传递过来的数据
this.towerInfo = JSON.parse(decodeURIComponent(option.data))
},
onHide() {
// 离开时销毁音频组件
this.stopAboutInfo()
},
methods: {
// 开始或者结束实时喊话
realTime() {
let that = this
// if (!that.socketInfo || !that.socketInfo.rtmp) {
// that.allToast('error', '获取推流地址异常,请稍后再试......')
// return
// }
that.isRealTime = !that.isRealTime
if (that.isRealTime) {
// 获取websocket相关信息
that.getWebSocketInfo()
}else{
// 停止推流
that.stopAboutInfo('end')
}
},
formatTime,
// 开始推流
start() {
let that = this
console.log("开始推流了")
that.context.start({
success: (a) => {
console.log("livePusher.start:" + JSON.stringify(a));
}
});
that.allToast('success', "请开始喊话!");
// 获取喊话秒数
that.getTimes()
// 设置心跳
that.setHeart()
that.timer = setInterval(()=>{
that.setHeart()
},10*1000)
},
// 停止相关信息
stopAboutInfo(type){
let that = this
that.isRealTime = false
that.timesNum = 0
// 停止计时器
if(that.timesTimer){
clearInterval(that.timesTimer)
that.timesTimer = null
}
// 停止心跳检测计时器
if(that.timer){
clearInterval(that.timer)
that.timer = null
}
if(type && type === 'end'){
that.allToast('success', "喊话结束!");
}
// 停止喊话
that.stopRealTime()
// 停止推流
that.stop()
},
// 停止推流
stop(){
let that = this
that.context.stop({
success: (a) => {
console.log(JSON.stringify(a));
}
});
},
// 心跳
setHeart(){
let that = this
let headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
postAction(that.objurl.heart,{sessionId:that.socketInfo.sessionId},headers)
},
// 停止喊话
stopRealTime(){
let that = this
let headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
postAction(that.objurl.stop,{sessionId:that.socketInfo.sessionId},headers)
},
// 获取喊话秒数
getTimes() {
let that = this
that.timesNum = 0
that.timesTimer = setInterval(() => {
that.timesNum += 1
}, 1 * 1000)
},
// 获取webSocket相关信息
getWebSocketInfo() {
let that = this
let params = {
towerId: that.towerInfo.id,
volume: that.volume
}
let headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
postAction(that.objurl.webSocktInfo, params, headers).then(res => {
if (res.success) {
that.socketInfo = {
rtmp: res.result && res.result.data && res.result.data.url ? res.result.data.url :
'',
sessionId: res.result && res.result.data && res.result.data.sessionId ? res.result
.data.sessionId : ''
}
if(!that.socketInfo || !that.socketInfo.rtmp){
that.allToast('error', res.result.resultMsg)
that.isRealTime = false
that.stopAboutInfo()
return
}
that.context = null
that.$nextTick(()=>{
that.context = uni.createLivePusherContext("livePusher", this);
that.$nextTick(()=>{
// 发起推流喊话
that.start();
})
})
} else {
that.allToast('error', res.message)
}
})
},
//消息提示方法
allToast(types, messages) {
this.$refs.uToast.show({
type: types,
message: messages,
})
},
statechange(e) {
console.log("statechange:" + JSON.stringify(e));
},
netstatus(e) {
console.log("netstatus:" + JSON.stringify(e));
},
error(e) {
console.log("error:" + JSON.stringify(e));
},
}
}
</script>
<style>
page {
height: 100%;
}
</style>
<style lang="scss" scoped>
.livePusher{
position: fixed;
left: -5000px;
top: -5000px;
}
.main_info {
height: 100%;
display: flex;
flex-direction: column;
background: #F5F6F7;
.top {
flex: 1;
padding: 20rpx 24rpx 0 24rpx;
.video_display {
height: 396rpx;
border-radius: 20rpx;
.vd_video_no {
width: 100%;
height: 100%;
text-align: center;
background: #000000;
font-size: 24rpx;
font-family: Microsoft YaHei UI;
color: #FFFFFF;
line-height: 396rpx;
}
}
.audio-list {
height: calc(100vh - 900rpx);
overflow-y: auto;
.audio-record {
margin-top: 29rpx;
.time {
text-align: center;
color: '#454C63';
font-size: 24rpx;
}
.record {
display: flex;
justify-content: flex-end;
margin-top: 23rpx;
.warning {
margin-top: 30rpx;
margin-right: 20rpx;
image {
width: 30rpx;
height: 30rpx;
}
}
.record-vocie {
height: 88rpx;
width: 214rpx;
line-height: 88rpx;
border-radius: 36rpx 36rpx 0rpx 36rpx;
background: #fff;
text-align: center;
font-size: 28rpx;
.duration,
.image {
display: inline-block;
vertical-align: middle;
margin: 0 auto;
}
.icon {
width: 34rpx;
height: 26rpx;
margin-left: 21rpx;
}
.icon-active {
width: 36rpx;
height: 27rpx;
}
}
}
}
}
.inp_itm {
display: flex;
flex-direction: row;
align-items: center;
padding: 30rpx;
background: #fff;
border-radius: 12rpx;
margin-top: 20rpx;
.left {
font-size: 24rpx;
font-weight: bold;
color: #141C3B;
margin-right: 20rpx;
.tips {
font-size: 24rpx;
color: #D7D7D8;
margin-left: 18rpx;
}
}
.right {
flex: 1;
font-size: 24rpx;
color: #141C3B;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-end;
overflow: hidden;
.riht_name {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
text-align: right;
word-wrap: break-word;
margin-right: 12rpx;
}
.no_chsoe {
color: #D7D7D8;
}
}
}
.play_btn {
margin-top: 80rpx;
position: fixed;
width: 100%;
bottom: 40rpx;
left: 0;
.custom-style {
color: #FFFFFF;
font-size: 15px;
background: #1577F1;
border-radius: 11px;
width: 80%;
}
}
.duration_shouting{
text-align: center;
margin-top: 40%;
}
}
.down {
box-shadow: 0 -3rpx 16rpx 0 rgba(0, 0, 0, 0.05);
border-radius: 30rpx 30rpx 0 0;
padding: 20rpx 24rpx;
.custom-style {
color: #fff;
background: #1577F1;
border-radius: 20rpx;
}
}
}
/deep/.riht_icon {
.u-icon__icon {
font-size: 24rpx !important;
line-height: 24rpx !important;
}
}
/deep/.al_select {
.u-action-sheet {
max-height: 600rpx;
overflow: auto;
}
}
.minus {
width: 44rpx;
height: 44rpx;
border-width: 2rpx;
border-color: #E6E6E6;
border-style: solid;
border-radius: 50%;
@include flex;
justify-content: center;
align-items: center;
margin-right: 10rpx;
}
.plus {
width: 44rpx;
height: 44rpx;
border-width: 2rpx;
border-color: #E6E6E6;
border-style: solid;
border-radius: 50%;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
justify-content: center;
align-items: center;
margin-left: 10rpx;
}
</style>```
- 发布:2023-07-18 14:04
- 更新:2023-07-18 14:04
- 阅读:147
产品分类: uniapp/App
PC开发环境操作系统: Windows
PC开发环境操作系统版本号: Windows 11 专业版
HBuilderX类型: 正式
HBuilderX版本号: 3.8.7
手机系统: Android
手机系统版本号: Android 14
手机厂商: 华为
手机机型: 华为P40pro
页面类型: vue
vue版本: vue2
打包方式: 云端
项目创建方式: HBuilderX
示例代码:
操作步骤:
点击开始推流,几秒后,APP闪退
点击开始推流,几秒后,APP闪退
预期结果:
点击开始推流,APP可以正常推流,APP不闪退
点击开始推流,APP可以正常推流,APP不闪退
实际结果:
点击开始推流,几秒后,APP闪退
点击开始推流,几秒后,APP闪退
bug描述:
点击开始推流几秒后APP闪退
0 个回复