Vue+Uniapp实现直播功能(推流拉流)

提示:


前言

目前有一个项目,需要做一个APP和一个PC端网页,主要功能是类似直播,经查阅资料,可采用uniapp+vue+推流拉流的技术,前端使用uniapp打开摄像头,并将视频流推流给后端,后端将视频流进行处理,形成m3u6或者flv格式的视频,前端使用flv.js进行播放视频流。


总共分为二部分,一篇是针对uniapp+vue(前端),另一篇是ngxin直播服务器的搭建(后端)。

一、核心插件

uniapp推流:(自带标签)live-pusher推流

vue拉流:flv.js视频播放器

1.uniapp推流

官方代码参考:实现推流

live-player | uni-app官网https://uniapp.dcloud.io/component/live-player

  • 创建uniapp项目
  • 在pages–>index–>新建live.nvue页面

必须是nvue后缀

 uniapp中的manifest.json文件,左侧菜单找到App模块配置,勾选 LivePusher(直播推流) 

页面代码:

<template>
    <view>
        <view class="account-form">
            <view class="uni-form-item">
                <view class="uni-input-wrapper">
                    <view class="uni-label uni-label-must">直播间标题</view>
                    <input class="uni-input" placeholder="请输入直播间标题" :value="form.liveroomTitle" @input="changeInput($event,'liveroomTitle')"/>
                </view>
            </view>
        </view>
        <button class="cu-btn bg-red margin-tb-sm lg" v-if="!startState" @click="saveForm">开始直播</button>
        <button class="cu-btn bg-red margin-tb-sm lg" v-if="startState" @click="downcast">关闭直播</button>
        <button class="cu-btn bg-red margin-tb-sm lg" @click="switchCamera">切换摄像头</button>
        <live-pusher
            id="livePusher"
            ref="livePusher"
            :style="pusherCalss"
            class="livePusher"
            url="rtmp://192.168.1.171:17002/live/huahua"
            mode="FHD"
            :muted="false"
            :enable-camera="true"
            :auto-focus="true"
            :beauty="1"
            whiteness="2"
            aspect="9:16"
            @statechange="statechange"
            @netstatus="netstatus"
            @error="error"
        ></live-pusher>
        // 官方给的一些按钮,具体调用在下面
        //<button class="btn" @click="start">开始推流</button>
        //<button class="btn" @click="pause">暂停推流</button>
        //<button class="btn" @click="resume">resume</button>
        //<button class="btn" @click="stop">停止推流</button>
        //<button class="btn" @click="snapshot">快照</button>
        //<button class="btn" @click="startPreview">开启摄像头预览</button>
        //<button class="btn" @click="stopPreview">关闭摄像头预览</button>
        //<button class="btn" @click="switchCamera">切换摄像头</button> -->
    </view>
</template>

<script>
export default {
    data() {
        return {
            // 视频宽高
            pusherCalss: {
                width: '200px',
                height: '300px'
            },
            // form本人测试请求的参数,不发请求可以不加
            form: {
                liveroomTitle: null, // 标题
                equipmentType: 1 // 设备类型(1.手机 2.电脑)
            },
            // 控制开启,关闭直播按钮的显示
            startState: false,// 直播状态(false 关闭)
        };
    },
    onReady() {
        // 注意:需要在onReady中 或 onLoad 延时
        this.context = uni.createLivePusherContext('livePusher', this);
    },
    onLoad() {
        // 获取可视区域高度,减去固定高度
        this.pusherCalss.width = wx.getSystemInfoSync().windowWidth;
        this.pusherCalss.height = wx.getSystemInfoSync().windowHeight;
    },
    mounted() {
        // 一进页面,先调用摄像头,保证摄像头是打开状态,不加也可以,手动开启,参考上面官方给出的那些按钮
        this.startPreview();
    },
    methods: {
        // 下面的这些方法,可以参考官网,具体查看每个方法的意义
        statechange(e) {
            console.log('statechange:' + JSON.stringify(e));
        },
        netstatus(e) {
            console.log('netstatus:' + JSON.stringify(e));
        },
        error(e) {
            console.log('error:' + JSON.stringify(e));
        },
        start: function() {
            this.context.start({
                success: a => {
                    this.startState = true;
                    console.log('livePusher.start:' + JSON.stringify(a));
                }
            });
        },
        close: function() {
            this.context.close({
                success: a => {
                    console.log('livePusher.close:' + JSON.stringify(a));
                }
            });
        },
        snapshot: function() {
            this.context.snapshot({
                success: e => {
                    console.log(JSON.stringify(e));
                }
            });
        },
        resume: function() {
            this.context.resume({
                success: a => {
                    console.log('livePusher.resume:' + JSON.stringify(a));
                }
            });
        },
        pause: function() {
            this.context.pause({
                success: a => {
                    console.log('livePusher.pause:' + JSON.stringify(a));
                }
            });
        },
        stop: function() {
            this.context.stop({
                success: a => {
                    this.startState = false;
                    console.log(JSON.stringify(a));
                }
            });
        },
        switchCamera: function() {
            this.context.switchCamera({
                success: a => {
                    console.log('livePusher.switchCamera:' + JSON.stringify(a));
                }
            });
        },
        startPreview: function() {
            this.context.startPreview({
                success: a => {
                    console.log('livePusher.startPreview:' + JSON.stringify(a));
                }
            });
        },
        stopPreview: function() {
            this.context.stopPreview({
                success: a => {
                    console.log('livePusher.stopPreview:' + JSON.stringify(a));
                }
            });
        },
        // 输入框改变(没有接口可以忽略,这里就是发送请求时起一个直播间的名字)
        changeInput: function(e, name) {
            this.form[name] = e.detail.value;
        },
        // 开始直播
        saveForm() {
            if(this.form.liveroomTitle == null || this.form.liveroomTitle == ""){
                return;
            }
            // 这里是我自己的测试请求,因为需要和vue数据同步,做一个开播关播的数据交互,大家如果用不到的话可以直接调用 this.start();
            getApp().$util.requestUrl(`/test/live/createLiveRecord?anchorId=2&liveroomTitle=${this.form.liveroomTitle}&equipmentType=${this.form.equipmentType}`).then(res => {
                console.log(res)
                if (res.status == 200) {
                    this.start();
                }
            });
        },
        // 关闭直播
        downcast(){
            // 同样,用不到接口只简单测试,调用this.stop();
            // vue的工具类等调用是this.$util;
            // uniapp使用getApp().$util
            getApp().$util.requestUrl(`/test/live/downcast?anchorId=2`).then(res => {
                console.log(res)
                if (res.status == 200) {
                    this.stop();
                }
            });
        }
    }
};
</script>

2.vue拉流

视频播放器有两种方式可以选择:(文件格式m3u8/flv)

video.js(vlc播放器是pc应用程序,可能有本地解码功能,一般js播放器是不具备解码功能的)

flv.js(一般情况下,视频流格式h264可以在flv.js播放器上正常播放)---推荐使用

问题一:跨域(前端配置无效,需要后端配置代理,前端配置代理是自欺欺人,部署上线时,前端代理并没有效果,还是得后端去做)

问题二:返回304状态码(视频流地址是静态固定地址,第一次收到后返回200,但是浏览器会自动缓存,第二次请求地址如果不变,获取到的一直是之前缓存的数据,就会返回304。应该设置为动态地址。如果只是使用静态固定地址测试,报304没有关系)

在这里插入图片描述


总结

感谢下面各位大神的文章!

【干货篇】Vue+UniApp实现直播功能_破烂码农的博客-CSDN博客_uniapp 直播uniapp(推流)+vue(拉流)+nginx+OBS实现直播一、先看效果vue拉流uniapp推流https://blog.csdn.net/weixin_43848873/article/details/118968726Nginx使用rtmp搭建流媒体服务器,实现hls直播_Handsome_Mr_Wang的博客-CSDN博客_nginx拉流rtmp为hls[nginx流媒体服务器] nginx+vue 使用rtmp实现hls直播项目里面需要使用直播技术,在网上看了一些文章,终于测试成功了,在此记录一下。这里借鉴了https://blog.csdn.net/Ricardo18/article/details/89359623这篇文章。准备对于RTMP、HLS、HTTP-FLV的介绍我就不在详细说了,借鉴的文章里讲的很详细。因为我实在win10(开发环境)下部署测试的,所以我就记录windows下部署怎么做NginxNginx下载地址我下载的是nhttps://blog.csdn.net/weixin_40758229/article/details/118968546

猜你喜欢

转载自blog.csdn.net/weixin_51258044/article/details/123884057