How to get video height and width from a MP4 URL w

2020-07-10 20:05发布

I'm writing a user script for downloading videos. The flash player of the web site use a JSON file.
The purpose of my script is to get the url of the video by downloading and parsing the video according to the web page. Currently it can download an extract the URL of the videos successfully.

The important part of the JSON file look like this :

    {
        "ammProfile": "AMM-HBBTV",
        "version": "VF",
        "versionProg": "1",
        "VFO": "HBBTV",
        "VMT": "mp4",
        "VUR": "http://vo.llnwd.net/v2/am/HBBTV/051332-074-A_SQ_2_VF_01464306_MP4-2200_AMM-HBBTV.mp4"
    }, {
        "ammProfile": "AMM-HBBTV",
        "version": "VF",
        "versionProg": "1",
        "VFO": "HBBTV",
        "VMT": "mp4",
        "VUR": "http://vo.llnwd.net/v2/am/HBBTV/051332-074-A_EQ_2_VF_01464315_MP4-1500_AMM-HBBTV.mp4"
    }

Both URL here are about the same video, this just is just the resolution which change.

So, How I can parse the relevant metadata without downloading the whole file? The standard for the H.264 video codec is very hard to read.

3条回答
孤傲高冷的网名
2楼-- · 2020-07-10 20:19

I use the xhr range header to download partial content, and then get the file info using videoconverter.js, a JS version of ffmpeg (whose license you should check if you plan to use any of this).

var videoUrl = 'https://dl.dropboxusercontent.com/u/17698405/bla.mp4';

var cmd = '-i myfile.mp4';
var args = parseArguments(cmd);
var sizeToDownload = 200*1024;

retrieveVideo(videoUrl, sizeToDownload, function(fileData) {
	ffmpeg_run({
		arguments: args,
		files: [{
			name: 'myfile.mp4',
			data: fileData
		}],
		print: print,
		printErr: print	
	});	
});

function parseArguments(text) {
  text = text.replace(/\s+/g, ' ');
  var args = [];
  text.split('"').forEach(function(t, i) {
    t = t.trim();
    if ((i % 2) === 1) {
      args.push(t);
    } else {
      args = args.concat(t.split(" "));
    }
  });
  return args;
}


function retrieveVideo(path, fragment_size, callback) {
  var xhr = new XMLHttpRequest();
  xhr.open("GET", path, true);
  xhr.responseType = "arraybuffer";
  xhr.setRequestHeader ('Range', 'bytes=0-' + (fragment_size - 1));

  xhr.onload = function (oEvent) {
    var arrayBuffer = xhr.response;
    if (arrayBuffer) {
      callback(new Uint8Array(arrayBuffer));
    }
  };

  xhr.send(null);
}

var textarea = document.getElementsByTagName('textarea')[0];

function print(text) {
	textarea.value += '> ' + text + '\n';
}
* { box-sizing: border-box }
html,body { height: 100%; margin: 0; padding: 0; overflow: hidden }
textarea { width: 100%; height: 100%; }
<script src="https://rawgit.com/bgrins/videoconverter.js/master/build/ffmpeg-all-codecs.js"></script>
<textarea></textarea>

查看更多
走好不送
3楼-- · 2020-07-10 20:21

you don't need to load the whole video to get the height:

function getVideoHeight(url, fnCallback){

var video=document.createElement("video");
  video.autoplay=true;
  video.oncanplay=function(){
     fnCallback(this.offsetWidth, this.offsetHeight);
     this.src="about:blank";
     document.body.removeChild(video);   
  };

  document.body.appendChild(video);
  video.src=url;

}


//test:

getVideoHeight(
  "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4", 
  function(w,h){ alert( w+"X"+h); }
); // shows: "640X360"
查看更多
淡お忘
4楼-- · 2020-07-10 20:29

You can use the Range HTTP header via XMLHttpRequest to get only a portion of the file:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

For example:

xhr.setRequestHeader ('Range', 'bytes=0-' + (fragment_size - 1))
xhr.setRequestHeader ('Content-Length', fragment_size) // This part isn't absolutely required on most (all?) browsers.
查看更多
登录 后发表回答