使用WebRTC进行Web视频会议
Web组件可以通过W3C标准协议接口拉起摄像头和麦克风。开发者在使用该功能时,需配置"ohos.permission.CAMERA"、"ohos.permission.MICROPHONE"权限。
通过在JavaScript中调用W3C标准协议接口navigator.mediaDevices.getUserMedia(),该接口用于拉起摄像头和麦克风。constraints参数是一个包含了video和audio两个成员的MediaStreamConstraints对象,用于说明请求的媒体类型。
在下面的示例中,点击index.html前端页面中的开起摄像头按钮,打开摄像头和麦克风。
- 应用侧代码。
// xxx.ets
import { webview } from '@kit.ArkWeb';
import { abilityAccessCtrl } from '@kit.AbilityKit';
@Entry
@Component
struct WebComponent {
controller: webview.WebviewController = new webview.WebviewController()
aboutToAppear() {
// 配置Web开启调试模式
webview.WebviewController.setWebDebuggingAccess(true);
let atManager = abilityAccessCtrl.createAtManager();
atManager.requestPermissionsFromUser(getContext(this), ['ohos.permission.CAMERA', 'ohos.permission.MICROPHONE'])
.then(data => {
let result: Array<number> = data.authResults;
let hasPermissions1 = true;
result.forEach(item => {
if (item === -1) {
hasPermissions1 = false;
}
})
if (hasPermissions1) {
console.info("hasPermissions1");
} else {
console.info(" not hasPermissions1");
}
}).catch(() => {
return;
});
}
build() {
Column() {
Web({ src: $rawfile('index.html'), controller: this.controller })
.onPermissionRequest((event) => {
if (event) {
AlertDialog.show({
title: 'title',
message: 'text',
primaryButton: {
value: 'deny',
action: () => {
event.request.deny();
}
},
secondaryButton: {
value: 'onConfirm',
action: () => {
event.request.grant(event.request.getAccessibleResource());
}
},
cancel: () => {
event.request.deny();
}
})
}
})
}
}
}
- 前端页面index.html代码。
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<video id="video" width="500px" height="500px" autoplay="autoplay"></video>
<canvas id="canvas" width="500px" height="500px"></canvas>
<br>
<input type="button" title="HTML5摄像头" value="开启摄像头" onclick="getMedia()"/>
<script>
function getMedia()
{
let constraints = {
video: {width: 500, height: 500},
audio: true
};
// 获取video摄像头区域
let video = document.getElementById("video");
// 返回的Promise对象
let promise = navigator.mediaDevices.getUserMedia(constraints);
// then()异步,调用MediaStream对象作为参数
promise.then(function (MediaStream) {
video.srcObject = MediaStream;
video.play();
});
}
</script>
</body>
</html>
托管网页中的媒体播放
Web组件提供了应用接管网页中的媒体播放的能力, 用来支持应用增强网页媒体播放能力(如:画质增强)的场景。
使用场景
网页播放媒体时,存在着一些不能令人满意的场景, 如网页视频不够清晰, 网页的播放器界面太简陋、功能太少,甚至一些视频不能播放。
此时,如果应用开发者想通过自己的或者第三方的播放器接管网页媒体播放来改善网页的媒体播放体验,则可以使用该功能。
实现原理
ArkWeb内核播放媒体的框架
不开启该功能时, ArkWeb 内核的播放架构如下:
说明:
- 上图中 1 表示 ArkWeb 内核创建 WebMdiaPlayer 来播放网页中的媒体资源。
- 上图中 2 表示 WebMdiaPlayer 使用系统解码器来渲染媒体数据。
开启该功能后, ArkWeb 内核的播放架构如下:
说明
- 上图中 1 表示 ArkWeb 内核创建 WebMdiaPlayer 来播放网页中的媒体资源。
- 上图中 2 表示 WebMdiaPlayer 使用应用提供的本地播放器(NativeMediaPlayer)来渲染媒体数据。
ArkWeb内核与应用的交互
开发指导
开启接管网页媒体播放
如果要使用接管网页媒体播放的功能,需要先开启该功能。
开发者可以通过 enableNativeMediaPlayer 来开启该功能。
// xxx.ets
import { webview } from '@kit.ArkWeb';
@Entry
@Component
struct WebComponent {
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Web({ src: 'www.example.com', controller: this.controller })
.enableNativeMediaPlayer({ enable: true, shouldOverlay: false })
}
}
}
创建本地播放器(NativeMediaPlayer)
该功能开启后, 每当网页中有媒体需要播放时, ArkWeb 内核会触发由 onCreateNativeMediaPlayer 注册的回调函数。
开发者则需要调用 onCreateNativeMediaPlayer 来注册一个创建本地播放器的回调函数。
该回调函数需要根据媒体信息来判断是否要创建一个本地播放器来接管当前的网页媒体资源。
- 如果应用不接管当前的为网页媒体资源, 需要在回调函数里返回 null 。
- 如果应用接管当前的为网页媒体资源, 需要在回调函数里返回一个本地播放器实例。
本地播放器需要实现 NativeMediaPlayerBridge 接口, 以便 ArkWeb 内核对本地播放器进行播控操作。
// xxx.ets
import { webview } from '@kit.ArkWeb';
// 实现 webview.NativeMediaPlayerBridge 接口。
// ArkWeb 内核调用该类的方法来对 NativeMediaPlayer 进行播控。
class NativeMediaPlayerImpl implements webview.NativeMediaPlayerBridge {
// ... 实现 NativeMediaPlayerBridge 里的接口方法 ...
constructor(handler: webview.NativeMediaPlayerHandler, mediaInfo: webview.MediaInfo) {}
updateRect(x: number, y: number, width: number, height: number) {}
play() {}
pause() {}
seek(targetTime: number) {}
release() {}
setVolume(volume: number) {}
setMuted(muted: boolean) {}
setPlaybackRate(playbackRate: number) {}
enterFullscreen() {}
exitFullscreen() {}
}
@Entry
@Component
struct WebComponent {
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Web({ src: 'www.example.com', controller: this.controller })
.enableNativeMediaPlayer({ enable: true, shouldOverlay: false })
.onPageBegin((event) => {
this.controller.onCreateNativeMediaPlayer((handler: webview.NativeMediaPlayerHandler, mediaInfo: webview.MediaInfo) => {
// 判断需不需要接管当前的媒体。
if (!shouldHandle(mediaInfo)) {
// 本地播放器不接管该媒体。
// 返回 null 。ArkWeb 内核将用自己的播放器来播放该媒体。
return null;
}
// 接管当前的媒体。
// 返回一个本地播放器实例给 ArkWeb 内核。
let nativePlayer: webview.NativeMediaPlayerBridge = new NativeMediaPlayerImpl(handler, mediaInfo);
return nativePlayer;
});
})
}
}
}
// stub
function shouldHandle(mediaInfo: webview.MediaInfo) {
return true;
}