设置视频源时未加载元数据回调

时间:2019-04-11 02:51:43

标签: javascript html html5-video blob

我需要通过输入标签上传的视频的视频尺寸。但是,当我将上传的视频设置为视频标签的来源时,不会调用loadmetadata事件。

在这种方法中,我设置了视频和收听者:

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 :(得分:0)

因为没有任何内容会强制浏览器预加载您的视频元素。 就其所知,您将永远不会播放此视频,因此它不会预加载其内容是有道理的。

您可以尝试通过调用其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">

答案 1 :(得分:-1)

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方法