いろんなユーザメディアを
使ってみよう
2015.08.03
WebRTC Meetup Tokyo #9
インフォコム株式会社
がねこまさし
@massie_g
1
いろんなユーザメディアを
使ってみよう
2015.08.03
WebRTC Meetup Tokyo #9
インフォコム株式会社
がねこまさし
@massie_g
2
メディアストリーム
今日のお話は、ここ!
3
PeerConnectionMediaStream
Chrome 44
Firefox 39 Firefox Nightly 42
おまじない
5
navigator.getUserMedia =
navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia;
カメラ
6
function startCamera() {
var gum = {video: true, audio: false};
navigator.getUserMedia(gum,
showMedia, errCallback
);
}
function showMedia(stream) {
localStreamURL = window.URL.createObjectURL(stream);
localVideo.src = localStreamURL;
}
マイク
7
function startMic() {
var gum = {video: false, audio: true};
navigator.getUserMedia(gum,
showMedia, errCallback
);
}
function showMedia(stream) {
localStreamURL = window.URL.createObjectURL(stream);
localVideo.src = localStreamURL; // ※本来はaudioを使う
}
カメラ+マイク
8
function startCamera() {
var gum = {video: true, audio: true};
navigator.getUserMedia(gum,
showMedia, errCallback
);
}
function showMedia(stream) {
localStreamURL = window.URL.createObjectURL(stream);
localVideo.src = localStreamURL;
}
カメラ+マイク MS Edge
9
// New API
function startCamera() {
navigator.mediaDevices.getUserMedia(
{video: true, audio: false}
).then(function(stream) {
video.srcObject = stream;
}).catch(function(err){
console.error('getUserMedia Err:', err);
});
}
カメラ+マイク MS Edge
10
// Old API
function startCamera() {
navigator. getUserMedia(
{video: true, audio: false},
function(stream) {
video.src = window.URL.createObjectURL(stream);
},
function(err){
console.error('getUserMedia Err:', err);
}
);
}
Fake カメラ
11
function startMic() {
var gum = {video: true, fake: true, audio: false};
navigator.getUserMedia(gum,
showMedia, errCallback
);
}
function showMedia(stream) {
localStreamURL = window.URL.createObjectURL(stream);
localVideo.src = localStreamURL;
}
Fake マイク
12
function startMic() {
var gum = {video: false, fake: true, audio: true};
navigator.getUserMedia(gum,
showMedia, errCallback
);
}
function showMedia(stream) {
localStreamURL = window.URL.createObjectURL(stream);
localVideo.src = localStreamURL;
}
スクリーン/ウィンドウキャプチャ
13
• Chromeでは、機能拡張(Extension)が必要
– http://www.slideshare.net/yusukenaka52/screenshare-public
• https:// を使う
ブラウザ側
var extensionId = ”xxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // extension id
chrome.runtime.sendMessage(extensionId, { getStream: true},
function(response) {
navigator.getUserMedia({
audio:false, // ※Audioと一緒には取得できない
video: { mandatory: { chromeMediaSource: "desktop",
chromeMediaSourceId: response.mediaid,
maxWidth : width, maxHeight : height }
}
}, successCallback, errorCallback);
}
);
スクリーン/ウィンドウキャプチャ
14
• ※注意:audioと一緒には取得できない
PeerConnection
MediaStream
MediaStream
PeerConnectionMediaStream
MediaStreamTrack
MediaStreamTrack
MediaStream
スクリーンキャプチャ
15
• Firefoxでは、about:configの設定で利用可能
• media.getusermedia.screensharing.enabled を新規に作成
– true に設定
• media.getusermedia.screensharing.allowed_domains
– 自分のサーバーのドメイン名、IPアドレスを追記
• https:// を使う
スクリーンキャプチャ
16
function startFirefoxScreen () {
var gum = {video: { mediaSource: "screen" }, audio: false};
// audio: true も可
navigator.getUserMedia(gum,
showMedia, errCallback
);
}
function showMedia(stream) {
localStreamURL = window.URL.createObjectURL(stream);
localVideo.src = localStreamURL;
}
ウィンドウキャプチャ
17
function startFirefoxScreen () {
var gum = {video: { mediaSource: "window" }, audio: false};
navigator.getUserMedia(gum,
showMedia, errCallback
);
}
function showMedia(stream) {
localStreamURL = window.URL.createObjectURL(stream);
localVideo.src = localStreamURL;
}
WebAudio oscillator
18
var context = new (window.AudioContext || window.webkitAudioContext)();
function startWebAudio() {
var oscillator = context.createOscillator();
oscillator.type = "sawtooth";
oscillator.frequency.value = 440; // 440Hz
// convert to mediastream
var destintation = context.createMediaStreamDestination();
oscillator.connect(destintation);
// start
var current = context.currentTime;
oscillator.start(current); // start now
oscillator.stop(current + 3.0); // stop 3 sec after
// show
showMedia(destintation.stream);
}
WebAudio from file (1)
19
var context = new (window.AudioContext || window.webkitAudioContext)();
// load file via XHR
function loadSound(file, callback) {
var xhr = new XMLHttpRequest();
xhr.open("GET", file, true);
xhr.responseType = "arraybuffer";
xhr.onreadystatechange=function(){ // OK for Chrome, Safari
if(xhr.readyState==4 && xhr.status==200){
console.log('xhr.readystate 200');
context.decodeAudioData(xhr.response,function(buf){
callback(buf);
}, function(){console.error('decode error');});
}
}
xhr.send();
}
WebAudio from file (2)
20
function startWebAudioFile() {
var audioclip;
loadSound('http://yourserver.com/sound.mp3',
function(buf) {
audioclip = buf;
var src = context.createBufferSource();
src.buffer = audioclip;
var destintation = context.createMediaStreamDestination();
src.connect(destintation);
src.start(0);
// show
showMedia(destintation.stream);
}
);
}
Canvasキャプチャ
21
• Firefox Nightlyで簡易実装。about:configの設定で利用可能
• canvas.capturestream.enabled
– true に設定
• https:// を使う ← http:// でも OK
Canvasキャプチャ
22
function startCanvas() {
localStream = canvas.captureStream(10); // FPS(必須)
if (localStream) {
localStreamURL = URL.createObjectURL(localStream);
localVideo.src = localStreamURL;
}
}
Canvasキャプチャ
23
function startCanvas() {
localStream = canvas.captureStream(10); // FPS(必須)
if (localStream) {
localStreamURL = URL.createObjectURL(localStream);
localVideo.src = localStreamURL;
}
}
MediaRecorder と組み合わせて使いたいらしい
オマケ
24
メディアソース一覧 Chrome
function getChromeMediaSource() {
MediaStreamTrack.getSources(function(sourceInfos) {
for (var i = 0; i != sourceInfos.length; ++i) {
var sourceInfo = sourceInfos[i];
if (sourceInfo.kind === 'audio') {
var id = sourceInfo.id;
var label = sourceInfo.label || 'microphone'; // label is available for https
// 適宜処理する
}
else if (sourceInfo.kind === 'video') {
var id = sourceInfo.id;
var label = sourceInfo.label || 'camera'; // label is available for https
} else {
console.log('Some other kind of source: ', sourceInfo);
}
}
});
25
デバイス一覧Firefox, Edge
function getDevices() {
navigator.mediaDevices.enumerateDevices()
.then(function(devices) {
devices.forEach(function(device) {
console.log(device.kind + ": " + device.label + " id = " + device.deviceId);
if (device.kind === 'audioinput') {
var id = device.deviceId;
var label = device.label || 'microphone'; // label is available for specific domain with https
// 適宜処理する
}
else if (device.kind === 'videoinput') {
var id = device.deviceId;
var label = device.label || 'camera'; // label is available for specific domain with https
// 適宜処理する
}
});
})
.catch(function(err) {
console.log(err.name + ": " + error.message);
});
}
26
オマケ2
27
なんちゃって デジタルズーム
28
<video>
<div style="overflow: hidden;">
Thank you!
29

WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう