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



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

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

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方法是否被调用,但是为什么加载的元数据侦听器没有得到回调?

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

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

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

最新更新