Нет обратного вызова загруженных метаданных при установке источника - PullRequest
0 голосов
/ 11 апреля 2019

Мне нужны размеры видео для видео, которое загружается через тег ввода.Но когда я устанавливаю загруженное видео в качестве источника тега видео, событие загруженных метаданных не вызывается.

В этом методе я устанавливаю видео и слушателя:

function getVideoDimensionsOf(objUrl){
    return new Promise(function(resolve){
        let video = document.createElement('video');
        //THIS GETS CALLED AS EXPECTED
        video.addEventListener( "loadedmetadata", function () {
            //THIS GETS NEVER CALLED
            let height = this.videoHeight;
            let width = this.videoWidth;
            console.log(height,width)
        }, false );
        video.src = objUrl;
    });
}

Вэтим методом я настроил обратный вызов для загрузки видео:

function localFileVideoPlayer() {
  var URL = window.URL || window.webkitURL
  var uploadSelectedFile = function (event) {
    var file = this.files[0]
    var type = file.type
    var fileURL = URL.createObjectURL(file)
    var fileReader = new FileReader();
    fileReader.onload = function() {
        var videofile = this.result;
        //do something here with video data
    };
    fileReader.readAsArrayBuffer(file);
    getVideoDimensionsOf(window.URL.createObjectURL(file))//-->>HERE I CALL THE FUNCTION THAT SHOULD SET THE VIDEO SOURCE
  }
  var inputNode = document.getElementById("videofile")
  inputNode.addEventListener('change', uploadSelectedFile, false)
}

И это поле загрузки html:

<div>
    Upload Video:
    <input id="videofile" type="file" accept="video/*"/>
</div>

Я проверил, что вызывается метод getVideoDimensionsOf, но почемупрослушиватель загруженных метаданных не получает обратный вызов?

Ответы [ 2 ]

0 голосов
/ 11 апреля 2019

localFileVideoPlayer();

function getVideoDimensionsOf(objUrl) {
  return new Promise(function(resolve) {
    let video = document.createElement("video");
    {
      // if you need to append the video to the document
      video.controls = true;
      document.body.appendChild(video);
    }
    //THIS GETS CALLED AS EXPECTED
    video.addEventListener(
      "loadedmetadata",
      function() {
        //THIS GETS NEVER CALLED
        let height = this.videoHeight;
        let width = this.videoWidth;
        console.log(height, width);
      },
      false
    );
    video.src = objUrl;
  });
}
function localFileVideoPlayer() {
  var URL = window.URL || window.webkitURL;
  var uploadSelectedFile = function(event) {
    var file = this.files[0];
    var type = file.type;
    var fileURL = URL.createObjectURL(file);
    var fileReader = new FileReader();
    fileReader.onload = function() {
      var videofile = this.result;
      //do something here with video data
    };
    fileReader.readAsArrayBuffer(file);
    getVideoDimensionsOf(window.URL.createObjectURL(file)); //-->>HERE I CALL THE FUNCTION THAT SHOULD SET THE VIDEO SOURCE
  };
  var inputNode = document.getElementById("videofile");
  inputNode.addEventListener("change", uploadSelectedFile, false);
}
<div>
  Upload Video:
  <input id="videofile" type="file" accept="video/*" />
</div>

В вашем коде вам нужно инициализировать событие изменения ввода, используя метод localFileVideoPlayer, поэтому я сначала выполнил этот метод. Затем, если вам нужно отобразить это видео в документе, вам нужно добавить элемент видео в документ, поэтому в getVideoDimensionsOf

есть метод appendChild
0 голосов
/ 11 апреля 2019

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

Вы можете попытаться форсировать эту предварительную загрузку, вызвав метод play().

function getVideoDimensionsOf(objUrl) {
  return new Promise(function(resolve) {
    let video = document.createElement('video');
    video.muted = true; // bypass Chrome autoplay policies
    video.addEventListener("loadedmetadata", function() {
      let height = this.videoHeight;
      let width = this.videoWidth;
      video.pause();
      resolve( { width, height } );
    }, false);
    video.src = objUrl;
    video.play();
  });
}

inp.onchange = e => {
  const url = URL.createObjectURL(inp.files[0]);
  getVideoDimensionsOf(url)
    .then(obj => {
      URL.revokeObjectURL(url);
      console.log(obj);
    });
}
<input type="file" id="inp" accept="video/*,.mp4">
...