iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0
Modern Web

從新開始學習p5.js畫出一片天系列 第 8

D08_Video元件的Capture操作

  • 分享至 

  • xImage
  •  

Video元件的Capture操作

今天來整理利用video開啟攝影機進行capture的影像輸入

先來看看p5.js的方式
使用 createCapture(VIDEO); 建立video元件,基本的程式如下

let can;
let capture;
function setup() {
	can = createCanvas(640, 480);
	can.id("can1");
	can.class("c1");
	can.position(0, 0);
	background(255, 255, 0);

	capture = createCapture(VIDEO);
	capture.size(640, 480);
	capture.id("cap1");
	capture.class("cp1");
	capture.position(640, 0);
	capture.hide();
	console.log(capture);
	console.log(capture.elt);
}

function draw() {
  image(capture, 0, 0, 640, 480);

  if(mouseIsPressed){
	capture.loadPixels();
	console.log(capture.pixels);
  }
}

產生的video元件, 物件類別為 MediaElement

<video playsinline="" crossorigin="anonymous" width="640" height="480" style="width: 640px; height: 480px; position: absolute; left: 640px; top: 0px;" id="cap1" class="cp1"></video>

在設定createCapture(VIDEO),其中VIDEO會以瀏覽器預設的camera作為capture的相機。
若有多個視訊來源的話,需要到chrome的「攝影機」設定區切換不同的視訊來源。
chrome的「攝影機」設定區

切換不同的視訊來源

其中除了筆電上的攝影機之外,像是外接的webcam,OBS的虛擬相機,影像擷取卡的影像輸入都可以作為視訊來源。
以下是OBS的虛擬相機設定方式,

  1. 先在「來源」區塊新增「視訊擷取裝置」
  2. 在「視訊擷取裝置」對話框中,點選要輪入的視訊來源。
  3. 在「控制項」區塊點選「啟動虛擬相機」
    這樣在OBS的畫面就會傳送出去了

視訊擷取裝置

啟動虛擬相機

在chrome的「攝影機」設定區會看到有4種的視訊來源
分別為

  1. OBS Virtual Camera,OBS的虛擬相機
  2. HDMI to U3 capture,影像擷取卡的影像輸入
  3. FaceTime HD Camera,筆電上的攝影機
  4. USB CAMERA,外接的webcam攝影機

如果要將capture的影像繪入到canvas的話,
要先執行 capture.hide(); 將capture隱藏起來,
再到 draw() 程式區塊中 執行 image(capture, 0, 0, 640, 480);

在p5.js中,image(img, x, y, w, h);
img可以繪入的種類有p5.Image,p5.Element,p5.Texture
其中 p5.Image 是以 createImage(w, h); 或是 loadImage(path); 所建立的圖像元件,
p5.Element 是以 createCanvas(), createGraphics(), createDiv(), createImg(), createInput()等指令所建立的圖像元件
p5.Texture 為使用 texture(img); 指令所建立的圖像元件,一般是指WEBGL建立的圖像。

利用navigator.mediaDevices建立視訊元件

let can;
let capture;
function setup() {
	can = createCanvas(640, 480);
	can.id("can1");
	can.class("c1");
	can.position(0, 0);
	background(255, 255, 0);

	navigator.mediaDevices.enumerateDevices().then((devices) => {
		//console.log(devices); 

		let device_name = "OBS Virtual Camera";
		devices.find((dev) =>{
			if(dev.label.indexOf(device_name) != -1){
				//console.log(dev.deviceId + ", " + dev.kind + ", " + dev.label);
				let constraints = {
					audio: false,
					video: {
						//facingMode: "user",   //-- "user","environment",
						//exact: "environment",
						deviceId: dev.deviceId
					}
				};
				capture = createCapture(constraints, (stream) => {
					console.log(stream);  // 回傳的物件類別是 MediaStream
					capture.size(640, 480);
					capture.id("cap1");
					capture.class("cp1");
					capture.position(640, 0);
					capture.hide();
				});
			}
		});
	});
}


function draw() {
  if(capture!=undefined){
	image(capture, 0, 0, 640, 480);
  }
  if(mouseIsPressed){
	capture.loadPixels();
	console.log(capture.pixels); //-- 回傳的資料類型 Uint8ClampedArray(1228800)
	//-- 陣列長度 640x480x4 = 1228800
  }
}

利用 navigator.mediaDevices.enumerateDevices().then((devices) => {});
可以查閱全部有連結的影音設備,透過篩選設定要連結的視訊來源。
同是可以利用 constraints 來設定影音來源的條件。
facingMode 可以設定 "user"(面向自拍的方向), "environment"(面向前方的方向)

capture = createCapture(constraints, (stream) => {}); 回傳的物件類別是 MediaStream
capture.pixels 回傳的資料類型 Uint8ClampedArray(1228800)

Uint8ClampedArray是 8位元整數的陣列類別,Uint8是指整數範圍是 0 ~ 255,Clamped是指若數值大於255, 則設定為255,若數值小於0,則設定為0,若數值是浮點數的話,則設定為最接近的整數,初始值為0。

另外,條件式是防止capture還沒準備好就要執行 image(capture, 0, 0, 640, 480); 造成 undefined 的錯誤。

let device_name = "OBS Virtual Camera"; 用來設定要連線的視訊來源,
要查閱有哪些連結設備,可以用 console.log(devices); 列示出來。

利用以下程式碼篩選要連結的視訊來源,

let device_name = "OBS Virtual Camera";
devices.find((dev) =>{
  if(dev.label.indexOf(device_name) != -1){ }
});

參考資料
Uint8ClampedArray
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray
createCapture()
https://p5js.org/reference/#/p5/createCapture


上一篇
D07_Video元件的基本操作
下一篇
D09_Video元件的YouTube影片操作
系列文
從新開始學習p5.js畫出一片天40
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言