WebRtc入门 – API说明

生活中,最使人疲惫的往往不是道路的遥远,而是心中的郁闷;最使人痛苦的往往不是生活的不幸,而是希望的破灭;最使人颓废的往往不是前途的坎坷,而是自信的丧失;最使人绝望的往往不是挫折的打击,而是心灵的死亡。所以我们要有自己的梦想,让梦想的星光指引着我们走出落漠,走出惆怅,带着我们走进自己的理想。

导读:本篇文章讲解 WebRtc入门 – API说明,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

一、媒体设备

1.1 摄像头

webrtc使用getUserMedia获取摄像头和话筒对应的媒体流

const Promise = navigator.mediaDevices.getUserMedia(constraints);

参数:constraints,这是一个MediaStreamConstraints对象,指定了获取媒体流的约束需求

返回值:promise,如果方法调用成功则得到一个MediaStream对象。如果调用失败,则抛出DOMException异常

异常说明

  • NotAllowedErrot: 请求的媒体源不能使用,以下情况会返回该错误:
    1. 当前页面内容不安全,没有使用HTTPS
    2. 没有通过用户授权
  • NotFoundError: 没有找到指定的媒体通道
  • NoReadableError: 访问硬件设备出错
  • OverconstrainedError: 不能满足指定的约束,错误对象包含constraint属性,用于指明不能满足的属性名称
  • SecurityError: Document对象禁用了媒体支持
  • AbortError: 用户已授权,但是因为其他原因导致访问硬件失败

实例

const constraints = {
	audio: true,
	video: {width: 1280, height: 720}
};

navigator.mediaDevices.getUserMedia(constraints)
.then((stream) => {
	const video = document.querySelector('video');
	video.srcObject = stream;
	video.onloadedmetadata = (e) => {
		video.play();
	};
})
.catch((err) =>{
	console.log(err.name + ":" + err.message);
});

1.2 共享屏幕

var promise = navigator.mediaDevices.getDisplayMedia(constraints);

参数:constraints,可选参数,MediaStreamConstraints约束对象,用于指定共享屏幕的约束需求。

返回值:pomise,如果调用成功则得到媒体流;如果调用失败,则返回一个DOMEx-ception对象

屏幕共享有可能泄漏用户隐私,处于安全考虑,webrtc规定:

  1. 每次调用getDisplayMedia方法都要弹出授权提示框,如果通过了授权,则不保存授权状态。
  2. getDisplayMedia方法必须由用户触发,且当前的document上下文处于激活状态。

异常说明

  • InvalidStateError: 由于用户操作(例如事件处理程序)而运行的代码未调用。此事件的另一个潜在原因: document在其上下文中getDisplayMedia()被调用的未完全激活;例如,它可能不是最前面的选项卡。
  • NotAllowedError: 用户拒绝访问屏幕区域的权限,或者当前浏览实例无权访问屏幕共享。
  • NotFoundError: 没有可供捕获的屏幕视频源。
  • NotReadableError: 用户选择了一个屏幕、窗口、选项卡或其他屏幕数据源,但发生了硬件或操作系统级别的错误或锁定,从而阻止了所选源的共享。
  • OverconstrainedError: 创建流后,应用指定constraints失败,因为无法生成兼容的流。
  • TypeError: constraints调用时不允许指定的包含约束getDisplayMedia()。这些不受支持的约束是advanced和任何约束,这些约束 又具有名为minor的成员 exact
  • AbortError: 其他失败情况

实例

async function startCapture(displayMediaOption) {
	let captureStream = null;
	
	try {
		captureStream = await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
	}catch(err) {
		console.error("Error:" + err);
	}
	return captureStream;
}

1.3 查询媒体设备

说明

var enumeratorPromise = navigator.mediaDevices.enumerateDevices();

返回值:enumeratorPromise,如果调用成功则得到一个包含成员MediaDevicesInfo的数组,该数组列出了所有可用的媒体设备;如果调用失败,则得到空值。MediaDevicesInfo的定义如下所示

定义

interface MediaDeviceInfo {
    readonly deviceId: string;
    readonly groupId: string;
    readonly kind: MediaDeviceKind;
    readonly label: string;
    toJSON(): any;
}

declare var MediaDeviceInfo: {
    prototype: MediaDeviceInfo;
    new(): MediaDeviceInfo;
};

type MediaDeviceKind = "audioinput" | "audiooutput" | "videoinput";

MediaDeviceInfo属性说明

属性 类型 说明
deviceId DOMString 设备ID
groupId DOMString 组ID
label DOMString 设备的描述信息,如”Full HD webcam (1bcf:2284)”
kind MediaDeviceKind 设备类型,取值为videoinput(视频输入设备)、audioinput(音频输入设备)、audiooutput(音频输出设备)

使用实例

if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
  console.log("enumerateDevices() not supported.");
  return;
}

// List cameras and microphones.

navigator.mediaDevices.enumerateDevices()
.then(function(devices) {
  devices.forEach(function(device) {
    console.log(device.kind + ": " + device.label +
                " id = " + device.deviceId);
  });
})
.catch(function(err) {
  console.log(err.name + ": " + err.message);
});

找出所有摄像头

function getConnectedDevice(type, callback) {
	navigator.mediaDevices.enumerateDevices()
	.then(devices => {
		const filtered = devices.filter(device => device.kind === type);
		callback(filtered);
	})
}

getConnectedDevices('videoinput', cameras => console.log('Cameras found', cameras));

1.4 监听媒体设备变化

为了在应用程序中监测媒体设备的变化,WebRTC提供了devicechange事件和ondevicec-hange事件句柄,与navigator.mediaDevices结合即可实时监控媒体设备的热插拔。

使用方法

// 1. 使用addEventListener监听事件
navigator.mediaDevices.addEventListener('devicechange', (event) => {
	updateDeviceList();
})

//2.使用ondevicechange事件句柄
navigator.mediaDevices.ondevicechange = (event) => {
	updateDeviceList();
}

更新所有摄像头

function updateCameraList(cameras) {
    const listElement = document.querySelector('select#availableCameras');
    listElement.innerHTML = '';
    cameras.map(camera => {
        const cameraOption = document.createElement('option');
        cameraOption.label = camera.label;
        cameraOption.value = camera.deviceId;
    }).forEach(cameraOption => listElement.add(cameraOption));
}

async function getConnectedDevices(type) {
    const devices = await navigator.mediaDevices.enumerateDevices();
    return devices.filter(device => device.kind === type);
}

//获取初始状态摄像头
const videoCameras = getConnectedDevices('videoinput');
updateCameraList(videoCameras);

// 监听事件并更新设备
navigator.mediaDevices.addEventListener('devicechange', event => {
    const newCameraList = getConnectedDevices('videoinput');
    updateCameraList(newCameraList);
});

1.5 从canvas获取媒体流

二、媒体约束

媒体约束是指媒体某一项技术特性,如分辨率、帧率等;媒体能力是当前设备能够支持的某个约束的量化指标,如帧率最高30;

媒体约束设定值是指包含了浏览器默认设定值的所有媒体约束。

  • MediaDevices.getSupportedConstraints:获取当前浏览器支持的约束数组。

  • MediaStreamTrack.getCapabilities:有了支持的约束数组,使用该方法获取这些约束的取值范围。

  • MediaStreamTrack.applyConstraints:根据应用程序的需要,调用该方法为约束指定自定义的值。

  • MediaStreamTrack.getConstraints:获取上述applyConstraints()方法传入的值。

  • MediaStreamTrack.getSettings:获取当前轨道上所有约束的实际值。

由于浏览器对约束的支持情况不同,并不是所有的约束所有浏览器都支持。所以在使用约束前,需要先使用方法MediaDevices.getSupportedConstraints进行检查。

let supportedConstraints = navigator.mediaDevices.getSupportedConstraints();

if (supportedConstraints && supportedConstraints.iso) {
	//iso约束存在
}

浏览器支持:https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackSupportedConstraints#properties_specific_to_shared_screen_tracks

2.1 约束类型

媒体约束包括媒体流约束(MediaStreamConstraints)和媒体轨道约束(MediaTrackConstraints)。

类型说明

类型 说明 示例
DOMString 字符串 {cursor: “always”}
ULongRange 具有范围的整数值,可指定最大值和最小值
max: 32位整型值,指定属性的最大值
mim: 32位整型值,指定属性的最小值
height:{min: 240, ideal: 720, max: 1080}
DoubleRange 通ULongRange,但是取值为双精度浮点型
ConstrainDOMString 字符串的约束,可取值如下:
1. DOMString
2. DOMString对象数组
3. 包含exact、ideal属性的对象,exact指定一个确切值,如果浏览器不能精确匹配则返回错误,而ideal指定理想值,如果浏览器不能精确匹配,则使用最接近的值
facingMode:{exact:‘user’}
aspectRatio: {ideal:1.77}
ConstrainBoolean 布尔值约束
1. true、false
2. 包含exact、ideal属性的对象
ConstrainULong 整型约束
1. 整型
2. 包含exact、ideal属性的对象
width: {min: 640, ideal:1280, max:1920}
ConstrainDouble 浮点型约束
1. 浮点型
2. 包含exact、ideal属性的对象

2.1.1 媒体流约束MediaStreamConstraints

interface MediaStreamConstraints {
    audio?: boolean | MediaTrackConstraints;
    peerIdentity?: string;
    video?: boolean | MediaTrackConstraints;
}

audio: 表示是否请求音频 eg: {audio: false}

video: 表示是否使用视频 eg:{video: false}

2.1.2 媒体轨道约束MeidaTrackConstraints

interface MediaTrackConstraints extends MediaTrackConstraintSet {
    advanced?: MediaTrackConstraintSet[];
}
interface MediaTrackConstraintSet {
    /通用约束
    groupId?: ConstrainDOMString; //组ID
    deviceId?: ConstrainDOMString; //设备ID,RTCPeerConnection关联的流不包含该越苏
    
    /视频约束
    aspectRatio?: ConstrainDouble;//视频宽高比 {aspectRatio: 16/9}
    //摄像头可取值 
    //1. user前置摄像头 
    //2.environment 后置摄像头 
    //3. left 左侧摄像头
    //4. right 右侧摄像头
    //RTCPeerConnection关联的流不包含改约束
    //{facingMode: 'user'}
    facingMode?: ConstrainDOMString;
    //帧率
    //{frameRate: {ideal: 10, max: 15}}
    frameRate?: ConstrainDouble;
    //视频高度
    //{height: 720}
    height?: ConstrainULong;
    //视频宽度
    //{width: 1280}
    width?: ConstrainULong;
    // 调整视频尺寸,可取值如下:
    // none:使用摄像头的原生分辨率
    // crop-and-scale: 允许对视频进行剪裁
    // {resizeMode: "none"}
    resizeMode?: ConstrainDOMString;
    
    /音频约束
    //自动增益控制,值为true则开启,值为false则关闭
    //{autoGainControl:true}
    autoGainControl?: ConstrainBoolean;
    //音轨数量
    //1.单声道
    //2.立体声
    // {channelCount:2}
    channelCount?: ConstrainULong;
	//回音消除,true为开启,false表示关闭
	//RTCPeerConnection关联的流不包含该约束
	//{echoCancellation: true}
    echoCancellation?: ConstrainBoolean;
	// 延时,单位秒,一般延时越低越好
	//RTCPeerConnection关联的流不包含该约束
	// {latency: 1}
    latency?: ConstrainDouble;
    //降噪,true开启,false关闭
    //{noiseSuppression: true}
    noiseSuppression?: ConstrainBoolean;
    //采样率
    //{sampleRate: 44100}
    sampleRate?: ConstrainULong;
    //采样大小
    //{sampleSize: 16}
    sampleSize?: ConstrainULong;
}

// 共享屏幕
// 在流中如何显示鼠标
// always: 一直显示光标
// motion:当移动鼠标时显示光标,静止时不显示
// never: 不显示光标
// {cursor: 'always'}
cursor ConstrainDOMString

//指定用户可以选择的屏幕内容
//application:应用程序
//browser: 浏览器标签页
//monitor: 显示器
//windows: 某个应用程序窗口
//{displaySurface: 'application'}
displaySurface ConstrainDOMString

//是否开启逻辑显示面
//{logicalSurface: true}
logicalSurface ConstrainBoolean

///图像采集约束
// 白平衡模式
// 1. none关闭白平衡模式
// 2. manual开启手动控制
// 3. single-shot开启一次自动白平衡
// 4. 开启连续自动白平衡
// {whiteBalanceMode:"none"}
whiteBalanceMode ConstrainDOMString
// 曝光模式
// 1. none关闭曝光模式
// 2. manual开启手动控制
// 3. single-shot开启一次自动曝光
// 4. 开启连续自动曝光
// {exposureMode:"none"}
exposureMode ConstrainDOMString
// 聚焦模式
// 1. none关闭聚焦模式
// 2. manual开启手动控制
// 3. single-shot开启一次聚焦
// 4. 开启连续自动聚焦
// {focusMode:"manual"}
focusMode ConstrainDOMString
// 兴趣点,与上面3种模式结合使用
// { pointsOfInterest:{ x: value , y: value  } }
pointsOfInterest ConstrainPoint2D
// 曝光补偿 ±3
exposureCompensation ConstrainDouble
//色温
colorTemperature ConstrainDouble
//感光度
iso ConstrainDouble
//亮度
brightness onstrainDouble
//对比度
contrast ConstrainDouble
// 饱和度
saturation CnstrainDouble
// 锐度
sharpness CnstrainDouble
// 聚焦距离
focusDistance CnstrainDouble
// 缩放
zoom CnstrainDouble
// 是否开启补光灯, true,false
torch CnstrainBoolean

2.2 使用方法

//1. 指定值
const constraints = {
	width: 1280,
	height: 720,
	aspectRatio: 3/2
};

//2. 指定最小值和理想值
const constraints = {
	frameRate: {min: 20},
	width:{min: 640, ideal: 1280},
	height:{min: 480, ideal: 720},
	aspectRatio: 3/2
};

//3.指定最小值、理想值和最大值
const constraints = {
	width: {min: 320, ideal: 1280, max: 1920},
	height: {min: 240, ideal: 720, max: 1080},
}

三、媒体流(MediaStream)

媒体流一般由多个媒体轨道组成,如音频轨道、视频轨道

获取媒体流的方式:

  1. 从摄像头或者麦克风获取流对象。
  2. 从共享屏幕获取流对象。
  3. 从canvas(HTMLCanvasElement)内容中获取流对象。
  4. 从媒体元素(HTMLMediaElement)获取流对象。

定义:

interface MediaStream extends EventTarget {
    readonly active: boolean;
    readonly id: string;
    onaddtrack: ((this: MediaStream, ev: MediaStreamTrackEvent) => any) | null;
    onremovetrack: ((this: MediaStream, ev: MediaStreamTrackEvent) => any) | null;
    addTrack(track: MediaStreamTrack): void;
    clone(): MediaStream;
    getAudioTracks(): MediaStreamTrack[];
    getTrackById(trackId: string): MediaStreamTrack | null;
    getTracks(): MediaStreamTrack[];
    getVideoTracks(): MediaStreamTrack[];
    removeTrack(track: MediaStreamTrack): void;
    addEventListener<K extends keyof MediaStreamEventMap>(type: K, listener: (this: MediaStream, ev: MediaStreamEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
    removeEventListener<K extends keyof MediaStreamEventMap>(type: K, listener: (this: MediaStream, ev: MediaStreamEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}

四、RTCPeerConnection

RTCPeerConnection 接口代表一个由本地计算机到远端的WebRTC连接。该接口提供了创建,保持,监控,关闭连接的方法的实现。

4.1 属性

以下属性均为只读属性:

  • canTrickleIceCandidates: 如果远端支持UDP打洞或支持通过中继服务器链接则该属性为true,该属性的值依赖于远端设置且仅在本地RTCPeerConnection.setRemoteDescription被调用时有效,如果该方法没被调用,则其值为null。
  • connectionState: 返回对等连接的状态,其值为:new、connecting、connected、disconnected、failed、closed。
  • currentLocalDescription: 返回一个连接本地端的RtcSessionDescription对象,包括可能由ICE代理生成的任何ICE候选者的列表。
  • currentRemoteDescription: 返回一个连接远程端的RtcSessionDescription对象,包括可能由ICE代理生成的任何ICE候选者的列表。
  • icsConnectionState: 返回RTCPeerConnection的ICE代理状态。其值为IcsConnectionState
  • icsGatheringState: 返回ICE聚集状态,通过这值可以之道ICE的candidate在什么时候完成,其值可能为: new、gathering、complete。
  • localDescription: 返回本地端RTCSessionDescription,如果尚未设置将会返回null。
  • peerIdentity: 返回一个RTCIdentityAssertion包括域名(idp)以及一个名称,代表这条连接的远端机器的身份识别信息。如果远端机器还没有被设置以及校验,这个属性会返回null。
  • pendingLocalDescription: 返回一个RTCSessionDescription对象,描述连接本地端的pending配置更改。
  • pendingRemoteDescription: 返回一个RTCSessionDescription对象,描述连接远程端的pending配置更改。
  • remoteDescription: 返回一个RTCSessionDescription对象,描述远程端的会话信息,包括配置和媒体信息。
  • sctp: 返回一个RTCSctpTransport对象,描述SCTP传输层,通过该层发送和接受的SCTP数据。如果尚未配置SCTP则此值为null
  • singlingState: 返回描述连接或重新连接到另一个对等端连接本地的信令过程状态。其值可能为:stable、hava-local-offer、have-remote-offer、have-local-pranswer、have-remote-pranswer。

最近在跟一个的免费直播,讲音视频开发,讲得不错分享给大家

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/137649.html

(1)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!