p5.js - 获取带有 id 的所有可用视频设备(网络摄像头)的数组

p5.js - Getting an array of all available video devices (webcams) with id

我想用 x 输出所有已连接网络摄像头的列表,并带有 ID。不幸的是,我总是收到以下错误消息(见图)。 有谁知道这可能是什么?感谢您的帮助!

这是我的代码:

const devices = [];
var list;
let video;

function setup() {
    list = navigator.mediaDevices.enumerateDevices().then(gotDevices);
    var constraints1 = {
    video: {
      deviceId: {
        exact: list[0].id
      },
    }
  };
    
    canvas = createCanvas(width,height);

    background(255);
    video = createCapture(constraints1);
}

function gotDevices(deviceInfos) {
  for (let i = 0; i !== deviceInfos.length; ++i) {
    const deviceInfo = deviceInfos[i];
    if (deviceInfo.kind == 'videoinput') {
      devices.push({
        label: deviceInfo.label,
        id: deviceInfo.deviceId
      });
    }
  }
  return devices;
}

----------------------------编辑(当前状态)-------- --------------

var deviceList = [];

function preload() {
  navigator.mediaDevices.enumerateDevices().then(getDevices);
}

function setup() {
  var constraints = {
  video: {
      deviceId: {
        exact: deviceList[1].id
      },
    }
  };

canvas = createCanvas(width, height);
background(255);
video = createCapture(constraints);
//console.log(deviceList);
}

function getDevices(devices) {

  //arrayCopy(devices, deviceList);
  for (let i = 0; i < devices.length; ++i) {
    let deviceInfo = devices[i];
    
      //Only get videodevices and push them into deviceList
      if (deviceInfo.kind == 'videoinput') {
        deviceList.push({
        label: deviceInfo.label,
        id: deviceInfo.deviceId
      });
//      console.log("Device name :", devices[i].label);
//      console.log("DeviceID :", devices[i].deviceId);
    }
  }
}

不幸的是,我在这里收到以下错误:

您要查找的信息在 'getDevices' 函数中。以下 运行s 在我的系统上,将在控制台 window 中显示设备名称和 ID。它还将为您可以在 setup() 中访问的音频和视频设备创建一个全局数组;请注意,deviceList 是在 preload() 中获得的,它在您的其余代码之前仅 运行 一次。

var deviceList = [];

function preload() {
  navigator.mediaDevices.enumerateDevices().then(getDevices);
}

function setup() {
  var constraints = {
  video:
  {
  }
};
canvas = createCanvas(width, height);
background(255);
video = createCapture(constraints);
//console.log(deviceList);
for (let x = 0; x < deviceList.length; x++) {
  console.log(deviceList[x]);
}

}

function getDevices(devices) {
  // console.log(devices); // To see all devices
  arrayCopy(devices, deviceList);
  for (let i = 0; i < devices.length; ++i) {
    let deviceInfo = devices[i];
    if (deviceInfo.kind == 'videoinput') {
      console.log("Device name :", devices[i].label);
      console.log("DeviceID :", devices[i].deviceId);
    }
  }
}

设备下拉列表

// N.B. Will not run in Processing IDE with Safari - Requires p5.js web editor and Chrome browser
// Loads deviceList array into pullDown list
// Drop Down List parts => a.)display field, b.)arrow, c.)listItems
// Syntax: List(x, y, w, h, itemH, txtSize)

let list;
let selectedItem = -1;
let drop = false;
let itemY = [];
var deviceList = [];

function preload() {
  navigator.mediaDevices.enumerateDevices().then(getDevices);
}

class List {

  constructor(x, y, w, h, itemH, txtSize) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.itemH = itemH;
    this.txtSize = txtSize;
    this.arrwX = this.x + this.w;
    this.arrwY = this.y;
    this.arrwH = this.h;
  }

  openVideoInput (videoSelected) {
    var constraints = {
    video: {
    deviceId: {
      exact: deviceList[videoSelected].id
      },
    }
  };
  createCapture(constraints);
}

press(mx, my) {
  // arrow touches
  if ((mx >= this.arrwX) && (mx <= this.arrwX+this.arrwH) && (my >= this.arrwY) && (my <= this.arrwY+this.arrwH)) {
    if (drop == true) {
      drop = false;
    } else {
      drop = true;
    }
  } // list touches
  if (drop) {
    if (deviceList.length > 0) {
      for (let j = 0; j < deviceList.length; j++) {
        if ((mx >= this.x) && (mx <= this.x + this.w) && (my >= itemY[j] ) && (my <= itemY[j] + this.itemH)) {
          selectedItem = j;
          console.log("selectedItem :", selectedItem);
          list.openVideoInput(selectedItem);
          drop = false;
        }
      }
    }
  }
}

displayFieldString(title) {
  fill(255); // background color
  rect(this.x, this.y, this.w, this.h);
  fill(0); // text color
  textSize(this.txtSize);
  text(title, this.x + 10, this.y + this.txtSize);
}

display() {
  if (selectedItem == -1) {
    this.displayFieldString("Select video input:");
  } else {
    this.displayFieldString(deviceList[selectedItem].label);
  }
  // arrow
  fill(255); // arrow background color
  rect(this.arrwX, this.arrwY, this.arrwH, this.arrwH);
  fill(0, 255, 0); // arrow color
  triangle(this.arrwX+5, this.arrwY+5, this.arrwX+this.arrwH-5, this.arrwY+5, this.arrwX+this.arrwH/2, this.arrwY+this.arrwH-5);
  // listItems
  if ((deviceList.length > 0) && (drop)) {
    for (let j = 0; j < deviceList.length; j++) {
      itemY[j] = (this.y + this.h) + j*this.itemH;
      fill(255);
      rect(this.x, itemY[j], this.w, this.itemH);
      fill(0);
      textSize(this.txtSize);
      text(deviceList[j].label, this.x + 10, itemY[j] + this.txtSize);
    }
  }
  if (!drop) {
    rect(this.x, this.y + this.h, this.w, 0);
  }
}
}

function setup() {
  createCanvas(400, 200);
  list = new List(30, 30, 320, 24, 24, 16);
}

function draw() {
  background(220);
  list.display();
}

function getDevices(devices) {

  for (let i = 0; i < devices.length; ++i) {
    let deviceInfo = devices[i];
    //Only get videodevices and push them into deviceList
    if (deviceInfo.kind == 'videoinput') {
      deviceList.push( {
      label:deviceInfo.label,
        id:deviceInfo.deviceId
      }
      );
    }
  }
}

function mousePressed() {
  list.press(mouseX, mouseY);
}

好的,现在我在 Internet 上进一步寻找解决方案并找到了一个,我想我也会 post 在这里。也许它仍然可以帮助别人。问题是当代码到达以下行时数组 deviceList[] 没有完全填充:

deviceList[1].id within setup()

解决此问题的最简单方法是post暂停 p5js 库的自动初始化,直到您的回调 getDevices() 完成其工作。再次感谢 apodidae 的帮助。

var deviceList = [];

navigator.mediaDevices.enumerateDevices().then(getDevices);

const setup = function () {
    
    var constraints = {
        video: {
            deviceId: {
                exact: deviceList[0].id
      },
    }
  };
    var constraints1 = {
        video: {
            deviceId: {
                exact: deviceList[1].id
      },
    }
  };
canvas = createCanvas(width, height);
background(255);
video = createCapture(constraints);
    video2 = createCapture(constraints1);
console.log(deviceList);
};

const draw = function () {
    
};


function startP5() {
    globalThis.setup = setup; // place callback setup() into global context
    globalThis.draw  = draw;
    new p5;
}


function getDevices(devices) {

  //arrayCopy(devices, deviceList);
  for (let i = 0; i < devices.length; ++i) {
    let deviceInfo = devices[i];
    
      //Only get videodevices and push them into deviceList
      if (deviceInfo.kind == 'videoinput') {
        deviceList.push({
        label: deviceInfo.label,
        id: deviceInfo.deviceId
      });
//      console.log("Device name :", devices[i].label);
//      console.log("DeviceID :", devices[i].deviceId);
    }
  }
    startP5();
}

Here再次link给对方讨论