• webrtc学习———记录三:mediaStreamTrack


    参考:

    https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack

    转自http://c.tieba.baidu.com/p/3312565203

    http://c.tieba.baidu.com/p/3312569139

    http://c.tieba.baidu.com/p/3312680272

     

    Network Stream API

    MediaStream:MediaStream用来表示一个媒体数据流。
    MediaStreamTrack在浏览器中表示一个媒体源。
     
    篇文章会对MediaStream进行讲解。
    MediaStream (别名 getUserMedia)
    MediaStream API 代表媒体数据流的同步。举个例子,从相机获取的视频流的同步和跟踪。
    理解MediaStream最简单的方法应该就是看看它的实际应用:
    在Chrome或Opera中, 打开这个demo simpl.info/gum。
    打开命令行。
    查看全局范围的数据流变量。
    每个MediaStream都有一个输入,这个输入可以理解成MediaStream生成的一个导航器。getUserMedia()可以传输视频元素或者是RTCPeerConnection。
    getUserMedia()方法有三个参数:
    一个 约束对象
    一个成功的回调,如果成功会回传一个MediaStream
    一个失败的回调,如果失败会回传一个error对象。
    每个MediaStream都有一个标签,像*Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ*一样,getAudioTradks()和getAudioTracks()方法会回传一个MediaStreamTracks对象的数组。
    针对 simpl.info/gum 这个例子来说,stream.getAudioTracks() 返回了一个空数组 (因为没有音频) , 假设已经有一个摄像头连接成功,getVideoTracks()会返回一个MediaStreamTrack对象的数组, 这个数组代表从摄像头得到的数据流。每个MediaStreamTrack都有一个类型 (*video* 或 *audio*), 和一个标签(代表一个或多个频道的音频或视频),在这个例子中,只有video track,但是很容易想象到可以用到这个例子的地方,比如一个聊天应用程序的前置摄像头、后置摄像头,一个屏幕分享软件等等。
    在Chrome或Opera中, URL.createObjectURL() 方法把MediaStream 转换成了一个 Blob URL,Blob URL可以看成一个视频元素的src。 (在Firefox和Opera中,视频的src可以通过数据流本身设定)。
    getUserMedia 也可以作为网络音频API的输入节点:
     1 function gotStream(stream) {
     2 window.AudioContext = window.AudioContext || window.webkitAudioContext;
     3 var audioContext = new AudioContext();
     4 
     5 // Create an AudioNode from the stream
     6 var mediaStreamSource = audioContext.createMediaStreamSource(stream);
     7 
     8 // Connect it to destination to hear yourself
     9 // or any other node for processing!
    10 mediaStreamSource.connect(audioContext.destination);
    11 }
    12 
    13 navigator.getUserMedia({audio:true}, gotStream);

    基于Chromium的应用和扩展可以合并getUserMedia。在manifest 中添加audioCapture 和 videoCapture权限可以在加载的时候得到(仅一次)授权,毕竟加载之后用户不会有对摄像头或麦克风的访问请求。同样,forgetUserMedia()也是只有一次授权。
    他的最终目的是使MediaStream能取到任意的数据源,不只是局限于摄像头或是手机。这将拿其兼容其他输入,如传感器等。
    需要注意的是getUserMedia()必须在服务器上使用,而不是本地文件中,否则的话将会抛出权限的错误。
    getUserMedia() 已经成功的融合了其它的JavaScript APIs和库:
    Webcam Toy 是一个photobooth应用,它使用WebGL来添加一些特效,让用户可以共享照片或是保存本地。
    FaceKat 是一个人脸追踪的游戏,使用headtrackr.js。
    ASCII Camera 使用Canvas API来生成ASCII码的图片。

    约束
    约束 在Chrome 24和Opera 18版本之后被引入。它们可以被用来设置 getUserMedia()和RTCPeerConnection addStream() 这些视频的流的分辨率。 约束的实现是为了制约例如视频高度和宽度的比例、帧率、和正反摄像头模式等等……
    针对约束,这里有一个例子: simpl.info/getusermedia/constraints.
    一个陷阱:getUserMedia约束在浏览器所有选项卡影响约束后完成后才设置,设置一个错误的值会发生以下错误:
    navigator.getUserMedia error:
    NavigatorUserMediaError {code: 1, PERMISSION_DENIED: 1}
    屏幕和标签捕获你同样可以利用MediaStream捕获屏幕和标签的数据源。它已经在Chrome中实现了像这个例子一样,但是在Opera上还没有实现。
    Chrome应用很多都已经实现了通过chrome.tabCaptureAPI 分享在线录播的功能。更多具体的信息,如屏幕录制的编码,请到 Screensharing with WebRTC上进行相关学习,但是目前只支持Chrome。
    信号: session控制,网络和多媒体信息
    WebRTC使用RTCPeerConnection进行两个浏览器之间的数据流的通信,但是也需要一种机制来协调沟通控制信息,这一个过程叫做信号。信号的方法和协议不是WebRTC指定的,而是RTCPeerConnection API的一部分。
    相应的,WebRTC应用开发者可以选择任意一种自己喜欢的消息协议,比如SIP或是XMPP,也可以选择任何适当的双工协议,apprtc.appspot.com 这个例子使用XHR和Channel API机制的信号,codelab是我们构建的通过Socket.io运行在 Node服务器上的应用。
    信号用来交换以下三个类型的信息:
    Session控制信息:用来初始化或是关闭通信,并报告错误。
    网络配置:本机的IP和端口等配置。
    媒体功能:编码解码器配置。 
    信号的配置必须没有任何差错,在完成点对点的传输之后就可以通过信号交换信息。
    举个例子,想像一下如果Jack Ma要和Jobs通信,这里有个demo来自于WebRTC W3C Working Draft, 它展示了信号的行为。下面的的代码假设某种信号机制的存在,在createSignalingChannel方法中创建。还要注意:在Chrome,Opera中使用RTCPeerConnection是目前的前提。
     1 var signalingChannel = createSignalingChannel();
     2 var pc;
     3 var configuration = ...;
     4 
     5 // run start(true) to initiate a call
     6 function start(isCaller) {
     7 pc = new RTCPeerConnection(configuration);
     8 
     9 // send any ice candidates to the other peer
    10 pc.onicecandidate = function (evt) {
    11 signalingChannel.send(JSON.stringify({ "candidate": evt.candidate }));
    12 };
    13 
    14 // once remote stream arrives, show it in the remote video element
    15 pc.onaddstream = function (evt) {
    16 remoteView.src = URL.createObjectURL(evt.stream);
    17 };
    18 
    19 // get the local stream, show it in the local video element and send it
    20 navigator.getUserMedia({ "audio": true, "video": true }, function (stream) {
    21 selfView.src = URL.createObjectURL(stream);
    22 pc.addStream(stream);
    23 
    24 if (isCaller)
    25 pc.createOffer(gotDescription);
    26 else
    27 pc.createAnswer(pc.remoteDescription, gotDescription);
    28 
    29 function gotDescription(desc) {
    30 pc.setLocalDescription(desc);
    31 signalingChannel.send(JSON.stringify({ "sdp": desc }));
    32 }
    33 });
    34 }
    35 
    36 signalingChannel.onmessage = function (evt) {
    37 if (!pc)
    38 start(false);
    39 
    40 var signal = JSON.parse(evt.data);
    41 if (signal.sdp)
    42 pc.setRemoteDescription(new RTCSessionDescription(signal.sdp));
    43 else
    44 pc.addIceCandidate(new RTCIceCandidate(signal.candidate));
    45 };

    首先,Jack Ma和Jobs要交换网络信息。 (表达式 *finding candidates*指向查找网络接口和端口的进程,通过ICE framework完成)
    Jack ma通过onicecandidatehandler创建一个RTCPeerConnection对象。
    handler在网络通的时候开始执行。
    Jack Ma发送将序列化的数据发送给Jobs,通过WebSock或其它机制建立信号。
    当Jobs收到这些序列化的信息之后,他会调用saddIceCandidate, 来添加远程连接的候选地址。
    WebRTC 客户端(也就是我们所说的端点,Jack Ma和Jobs)也需要确定和交换本地和远程音频、视频的媒体信,如分辨率和编解码器等功能。
     
  • 相关阅读:
    [leetcode.com]算法题目
    [leetcode.com]算法题目
    [leetcode.com]算法题目
    [实战演练]2014年人人公司应届生校招技术笔试题
    [杂谈]笔试中一些数字逻辑推理(非技术)
    [实战演练]腾讯2013年校招软件开发类笔试题目(选择题部分)
    [实战演练]史上最长最醒目的队名
    [Linux]在linux中,常常用到ctrl和其他按键组合,常用的有哪些及意义呢
    [linux] grep awk sort uniq学习
    [IDEA] 快捷键学习
  • 原文地址:https://www.cnblogs.com/xiaoerhei/p/4071409.html
Copyright © 2020-2023  润新知