Skip to content

Instantly share code, notes, and snippets.

@astroza
Created February 26, 2018 19:10
Show Gist options
  • Save astroza/a30a06e1001943d3a4aa49bf04ad22db to your computer and use it in GitHub Desktop.
Save astroza/a30a06e1001943d3a4aa49bf04ad22db to your computer and use it in GitHub Desktop.
Tool to analyse segments
/* fastroza@ned.cl
*/
const spawn = require('child_process').spawn;
const frame_regex = /\[FRAME\]\n([\/\w=\n\.:\d\-_\s]*)\[\/FRAME\]\n/g;
const value_regex = /([\w_]*)=([\/\d\.\w_:]*)/g;
function digest_frame(str)
{
ret = {};
while ( (match = value_regex.exec(str)) ) {
ret[match[1]] = match[2];
}
return ret;
}
function for_each_frame(str, frame_cb)
{
while ( (match = frame_regex.exec(str)) ) {
frame_cb(digest_frame(match[1]));
}
}
var video_frames = [];
var audio_frames = [];
probe = spawn("/usr/bin/ffprobe", ["-show_frames", process.argv[2]]);
probe.stdout.on('data', (data) => {
for_each_frame(data, function(frame) {
if(frame.media_type == 'video') {
video_frames.push({pts: parseFloat(frame.pkt_pts_time), picture_number: frame.coded_picture_number, duration: parseFloat(frame.pkt_duration_time)});
} else if(frame.media_type == 'audio') {
audio_frames.push({pts: parseFloat(frame.pkt_pts_time), duration: parseFloat(frame.pkt_duration_time)});
}
});
});
probe.on('close', function() {
var video_length = 0;
if(video_frames.length > 2) {
var duration = video_frames[1].pts - video_frames[0].pts;
var base = video_frames[0].pts;
var base_index = 0;
for(var i in video_frames) {
var diff = (video_frames[base_index].pts+(i-base_index)*duration) - video_frames[i].pts;
if(Math.abs(diff) > 0.0001) {
console.log("VIDEO: PTS " + video_frames[i].pts + " should be " + (video_frames[base_index].pts+(i-base_index)*duration))
base_index = i;
base = video_frames[base_index].pts;
}
}
video_length = (video_frames[video_frames.length-1].pts + video_frames[video_frames.length-1].duration - video_frames[0].pts);
}
var audio_length = 0;
if(audio_frames.length > 2) {
var global_diff = 0;
var drift = 0;
console.log("First audio pts: " + audio_frames[0].pts);
for(i = 0; i < audio_frames.length-1; i++) {
var diff = audio_frames[i].pts + drift + audio_frames[i].duration - audio_frames[i+1].pts;
global_diff += diff;
if(Math.abs(diff) > 0.0001) {
console.log("AUDIO["+(i+1)+"]: PTS " + audio_frames[i+1].pts + " should be " + (audio_frames[i].pts + drift + audio_frames[i].duration))
}
}
console.log("Last audio pts: " + audio_frames[audio_frames.length-1].pts, "next frame: " + (audio_frames[audio_frames.length-1].pts + audio_frames[audio_frames.length-1].duration));
console.log("Global diff: " + global_diff)
audio_length = (audio_frames[audio_frames.length-1].pts + audio_frames[audio_frames.length-1].duration - audio_frames[0].pts);
}
console.log("Video length: ", video_length);
console.log("Audio length: ", audio_length);
console.log("length(video)-length(audio): ", video_length - audio_length);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment