首页 前端知识 用HTML5实现使用手机端摄像头实现webrtcs视频流

用HTML5实现使用手机端摄像头实现webrtcs视频流

2024-08-24 23:08:02 前端知识 前端哥 169 71 我要收藏

webrtc流媒体的播放,本质上也是基于建立端到端的RTC连接、接收推送过来的视频流数据的过程。webrtc流地址本质上就具有很强的规则性,其中包含信令服务器地址、基本参数等。
SRS(Simple Real-Time Media Server)是一个强大的开源的流媒体服务器, webrtcs视频流的播放本身就是一个订阅(播放)的过程,因此 SRS 源码中自然包含播放的代码,即 
srs.sdk.js 是基于 SRS 实时视频服务器、对浏览器支持的 WebRTC 基础功能的封装

系统需要的环境

- 1,Srs的安装Docker | SRS

- 2,搭建https://www.rabbitmq.com/

RabbitMQ主要是用于后台的数据交付到队列内,然后前端页面使用ws(wss)来展示数据。朋友们可以根据业务需求自行修改.

// 下面的代码是回流,显示数据到页面上
//换域名如果你的域名启用https,Stomp.client要使用wss://
//换域名如果你的域名启用http,Stomp.client要使用ws://
//如果使用http://127.0.0.1 ,就使用Stomp.client要使用ws://
//var client = Stomp.client('wss://rabbit.ggiooo.com:15674/wss');
var client = Stomp.client('wss://rabbit.ggiooo.com:15674/ws');
//订阅rabbmiq队列
var on_connect = function(x) {
      id = client.subscribe("/queue/rtc_publisher_queue", function(d) {
            console.log("d ===>",d)
            vm.testprint(d);
        });
};
var on_error =  function() {
      console.log('error');
 };
client.connect('guest', 'guest', on_connect, on_error, 'dou');

Stomp.client就是连接ws rabbitMQ队列协议。然后建立on_connect。

client.connect('用户名','密码',on_connet,on_error,'主机名')

二,启动js rtc推流

sdk = new SrsRtcPublisherAsync();
....
// For example: webrtc://r.ossrs.net/live/livestream
var url = $("#txt_url").val();
sdk.publish(url).then(function(session){
   ...
}

url是SRS服务端的webrtc地址

文档链接:Docker | SRS

打开地址:http://localhost:1985/rtc/v1/whep/?app=live&stream=livestream

你就能找到WebRTC协议的地址

关于SRS的教程很多,我这边不详细说明SRS。请百度查询SRS

三,下面是index.html的核心代码。

<!DOCTYPE html>
<html>
<head>
    <title>SRS</title>
    <meta charset="utf-8">
    <style>
        body{
            padding-top: 30px;
        }
    </style>
    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/>
    <script type="text/javascript" src="js/jquery-1.12.2.min.js"></script>
    <script type="text/javascript" src="js/adapter-7.4.0.min.js"></script>
    <script type="text/javascript" src="js/srs.sdk.js"></script>
    <script type="text/javascript" src="js/winlin.utility.js"></script>
    <script type="text/javascript" src="js/srs.page.js"></script>
    <script src="js/stomp.js"></script>
    <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>

</head>
<body>

<div class="container">
    <div class="form-inline">
        URL:
        <input type="text" id="txt_url" class="input-xxlarge" value="">
        <button class="btn btn-primary" id="btn_publish">开始推流</button>
    </div>

    <label></label>
    <video id="rtc_media_player" width="320" autoplay muted></video>

    <label></label>
    SessionID: <span id='sessionid'></span>
    <div style="display:none">
    <label></label>
    Audio: <span id='acodecs'></span><br/>
    Video: <span id='vcodecs'></span>
    </div>

     <div id="app" style="margin: 10px;" >
        <div v-for="(item,i) in lists">
            <img :src="item.scene_img" style="width:220px;height:220px;  " />
            <p style="font-size:14px">[视频创建时间:{{item.created_at}}]-[AI完成时间{{item.last_at}}]
                <br> {{item.scene_msg}}</p>
        </div>
    </div>

</div>
 

<script type="text/javascript">
$(function(){
    var sdk = null; // Global handler to do cleanup when republishing.
   
        $('#rtc_media_player').show();

 
        // Close PC when user replay.
        if (sdk) {
            sdk.close();
        }
        sdk = new SrsRtcPublisherAsync();

        // User should set the stream when publish is done, @see https://webrtc.org/getting-started/media-devices
        // However SRS SDK provides a consist API like https://webrtc.org/getting-started/remote-streams
        $('#rtc_media_player').prop('srcObject', sdk.stream);
        // Optional callback, SDK will add track to stream.
        // sdk.ontrack = function (event) { console.log('Got track', event); sdk.stream.addTrack(event.track); };

        // https://developer.mozilla.org/en-US/docs/Web/Media/Formats/WebRTC_codecs#getting_the_supported_codecs
        sdk.pc.onicegatheringstatechange = function (event) {
            if (sdk.pc.iceGatheringState === "complete") {
                $('#acodecs').html(SrsRtcFormatSenders(sdk.pc.getSenders(), "audio"));
                $('#vcodecs').html(SrsRtcFormatSenders(sdk.pc.getSenders(), "video"));
            }
        };

        // For example: webrtc://r.ossrs.net/live/livestream
        var url = $("#txt_url").val();    //rtmp地址
        sdk.publish(url).then(function(session){
            $('#sessionid').html(session.sessionid);
            $('#simulator-drop').attr('href', session.simulator + '?drop=1&username=' + session.sessionid);
        }).catch(function (reason) {
            // Throw by sdk.
            if (reason instanceof SrsError) {
                if (reason.name === 'HttpsRequiredError') {
                    alert(`WebRTC推流必须是HTTPS或者localhost:${reason.name} ${reason.message}`);
                } else {
                    alert(`${reason.name} ${reason.message}`);
                }
            }
            // See https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia#exceptions
            if (reason instanceof DOMException) {
                if (reason.name === 'NotFoundError') {
                    alert(`找不到麦克风和摄像头设备:getUserMedia ${reason.name} ${reason.message}`);
                } else if (reason.name === 'NotAllowedError') {
                    alert(`你禁止了网页访问摄像头和麦克风:getUserMedia ${reason.name} ${reason.message}`);
                } else if (['AbortError', 'NotAllowedError', 'NotFoundError', 'NotReadableError', 'OverconstrainedError', 'SecurityError', 'TypeError'].includes(reason.name)) {
                    alert(`getUserMedia ${reason.name} ${reason.message}`);
                }
            }

            sdk.close();
            $('#rtc_media_player').hide();
            console.error(reason);
        });
    };

    $('#rtc_media_player').hide();
    var query = parse_query_string();
    srs_init_rtc("#txt_url", query);

    $("#btn_publish").click(startPublish);
    // Never play util windows loaded @see https://github.com/ossrs/srs/issues/2732
    if (query.autostart === 'true') {
        window.addEventListener("load", function(){ startPublish(); });
    }

   

});
</script>
</body>
<script>   
    // 下面的代码是回流,显示数据到页面上
    //换域名如果你的域名启用https,Stomp.client要使用wss://
    //换域名如果你的域名启用http,Stomp.client要使用ws://
    //如果使用http://127.0.0.1 ,就使用Stomp.client要使用ws://
    //var client = Stomp.client('wss://rabbit.ggiooo.com:15674/wss');
    var client = Stomp.client('wss://rabbit.ggiooo.com:15674/ws');
    //订阅rabbmiq队列
    var on_connect = function(x) {
        id = client.subscribe("/queue/rtc_publisher_queue", function(d) {
            console.log("d ===>",d)
            vm.testprint(d);
        });
    };
    var on_error =  function() {
        console.log('error');
    };
    client.connect('guest', 'guest', on_connect, on_error, 'dou');
</script>


<script>
var _data ={
      lists :[]
};
var vm=new Vue({
    el:'#app',
    data:_data,
    onLoad:function(){
    },
    mounted:function(){
    },
    methods:{
        addValueToFront(newValue) {
            this.lists.unshift(newValue);  //向数组添加数组
            console.log(this.lists);
        },
        testprint(d) {
            console.log("57 >>>")            
            let jsonObject = JSON.parse(d.body);
            if (jsonObject.hasOwnProperty('scene_img')) {
                let scene_img = 'https://hs.ggiooo.com/upimgloads/'+ 
                     jsonObject.scene_img.replace("/www/srs5/output/images/",'')
                let scene_msg =jsonObject.scene_msg
 this.addValueToFront({'scene_img':scene_img,'scene_msg':scene_msg,'created_at':jsonObject.created_at,'last_at':jsonObject.last_at})
             }
        }

    }
    
})

</script>

</html>

3-1,关于wss的用法:

链接:http://ossrs.net/lts/zh-cn/docs/v6/doc/getting-started#webrtc-using-https

【WebRTC using HTTPS】推流时, 若需要在非本机使用WebRTC,比如SRS运行在远程服务器,在笔记本或者手机上使用WebRTC,则需要开启HTTPS API。

直白说就是要加上请使用你的证书文件,代替上面配置中的key和cert

3-2,推流的逻辑图

3-3,上面的代码没办法实现手机摄像头使用后置

//修改js/srs.sdk.js
//函数SrsRtcPublisherAsync名

    self.constraints = {
        audio: true,
        video: {
            facingMode: { exact: "environment" },  //后置摄像头
            width: {ideal: 320, max: 576}
        }
    };

以上的实现是作者【黑金】业务需求经过采坑已经实现的,不是网上抄袭的。如果对webrtcs推流感兴趣的朋友,欢迎加微信来聊。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/16800.html
评论
发布的文章

jQuery File Upload 使用教程

2024-09-03 02:09:33

jQuery笔记

2024-05-03 18:05:51

jQuery-Spectragram 使用教程

2024-09-03 02:09:26

echarts问题汇总

2024-09-03 02:09:12

echarts自定义悬浮提示

2024-09-03 02:09:12

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!