переданный видеоформат getUserMedia / MediaRecorder больше, чем запрашиваемый формат.Как сказать? - PullRequest
0 голосов
/ 24 января 2019

Фон:

В Windows 10 я использую getUserMedia (gUM) и MediaRecorder в Google Chrome (v71) для захвата и кодирования видеопотока.

  • Я использую параметр ограничений для gUM, чтобы сообщить ему, что я хочу формат видео 352x288.
  • Я запрашиваю video/webm; codecs="avc1.42E01E" в качестве MIME-типа закодированного потока (это H.264 в штучной упаковке Matroska ).

  • В качестве источника видео я выбираю непристойную веб-камеру, встроенную в ноутбук.Он называется «EasyCamera» производства DMAX-AVC.Соблазнительно назвать его CheezyCamera.

Видеопоток генерируется просто отлично.

Проблема:

Размеры закодированного видео в потоке 440x360 , а не мои запрошенные 352x288 .Эта информация встроена в записанный поток и видна только потребителю этих данных.Использование различных API-интерфейсов показывает, что метаданные потока gUM, MediaRecorder и <video> элемента считают, что измерения - это те, о которых я просил.

Конечно, веб-камера, gUM и MediaRecorder рассматривают параметр ограничений как предложения.и можете ответить чем-то другим.В этом случае они отвечают с 440x360, когда я запрашиваю 352x288.Эта система функционирует как задумано;это не моя проблема.

Для пояснения, неожиданные размеры 440x360 видны только потребителю записанного потока.Я надеюсь найти способ узнать, что сигнальная цепочка веб-камеры, gUM и MediaEncoder на стороне производителя производит разрешение, отличное от того, которое я запрашивал.

Как потребитель потока узнает размеры потока?Они находятся в блоках Matroska «PixelWidth» и «PixelHeight» и встроены в поток H.264.(Как ни странно, учитывая, что это программное решение выбрано, оно не является целым числом макроблоков 16x16. Конечно, оно все еще работает.)

Я не могу проанализировать записанные данные в браузере, потому что этохранится в непрозрачных BLOB-объектах.

Когда я использую другую, более совершенную веб-камеру (Logitech C615), мой кодированный видеопоток соответствует требуемому размеру.

Мой вопрос:

Есть ли какой-нибудь способ в цепочке сигналов веб-камеры / gUM / MediaRecorder / <video> найти фактические размеры закодированного потока в браузере, реально записывающем поток?То есть я могу найти ответ сигнальной цепочки на мои запрошенные измерения без декодирования сгенерированного потока?

Ответы [ 3 ]

0 голосов
/ 29 января 2019

Возможно, вам потребуется использовать ключевое слово ограничения exact, как в в этом тесте

const sdPalConstraints = {
  video: {width: {exact: 352}, height: {exact: 288}}
};
// Assuming |video| exists and represents a <video> element.
navigator.mediaDevices.getUserMedia(sdPalConstraints)
                      .then(stream) => {video.srcObject = stream};

Это не гарантирует, что веб-камера будет транслироваться в этом разрешении, но еслиполученный один отличается от запрошенного, VideoTrackAdapter будет задействован для его адаптации для вас (и для MediaRecorder).

0 голосов
/ 02 февраля 2019

После того, как я попробовал различные варианты, предложенные другими авторами этого вопроса, мне не удалось решить эту проблему.

Я пришел к выводу, что это ошибка где-то в веб-камере цепочки сигналов для Google Chrome и GUM.

0 голосов
/ 27 января 2019

Используйте MediaStream.getVideoTracks() метод для получения видео дорожки ( MediaStreamTrack ), затем используйте MediaStreamTrack.getSettings() для получения MediaTrackSettings объекта , который содержит высоту и ширину видео потока.

Поэтому, если я запрашиваю видео с 0 высотой, указанной как «Ограничения», я получаю видео с высотой 1 пиксель. Во время потоковой передачи мы можем получить как высоту, которую я запрашивал, так и высоту, которую я получаю как вывод.

function handleMediaStream(mystream){
  let videoStreamTrack = mystream.getVideoTracks()[0];
  let constraints = videoStreamTrack.getConstraints();
  console.log(constraints.width, constraints.height);
  // outputs: 640 0
  let settings = videoStreamTrack.getSettings();
  console.log(settings.width, settings.height);
  // outputs: 640 1
}

let videoConstraints = { width: 640, height: 0 }
navigator.mediaDevices.getUserMedia({ video: videoConstraints })
.then(function create_media_recorder(mystream) {
  handleMediaStream(mystream);
});
...