-
-
Save alexdrean/a027dd89a90a6d0aa54983f87f34a5c4 to your computer and use it in GitHub Desktop.
// 1. Open the browser developper console on the network tab | |
// 2. Start the video | |
// 3. In the dev tab, locate the load of the "master.json" file, copy its full URL | |
// 4. Run: node vimeo-downloader.js "<URL>" | |
// (done automatically now) 5. Combine the m4v and m4a files with mkvmerge | |
const fs = require('fs'); | |
const url = require('url'); | |
const https = require('https'); | |
const { exec } = require('child_process'); | |
let masterUrl = process.argv[2]; | |
if (!masterUrl.endsWith('?base64_init=1')) { | |
masterUrl+= '?base64_init=1'; | |
} | |
getJson(masterUrl, (err, json) => { | |
if (err) { | |
throw err; | |
} | |
const videoData = json.video.sort((v1,v2) => v1.avg_bitrate - v2.avg_bitrate).pop(); | |
const audioData = json.audio.sort((a1,a2) => a1.avg_bitrate - a2.avg_bitrate).pop(); | |
const videoBaseUrl = url.resolve(url.resolve(masterUrl, json.base_url), videoData.base_url); | |
const audioBaseUrl = url.resolve(url.resolve(masterUrl, json.base_url), audioData.base_url); | |
processFile('video', videoBaseUrl, videoData.init_segment, videoData.segments, json.clip_id + '.m4v', (err) => { | |
if (err) { | |
throw err; | |
} | |
processFile('audio', audioBaseUrl, audioData.init_segment, audioData.segments, json.clip_id + '.m4a', (err) => { | |
if (err) { | |
throw err; | |
} | |
console.log('combining video and audio...'); | |
let combineCmd = 'ffmpeg -i ' + json.clip_id + '.m4v -i ' + json.clip_id + '.m4a -c copy ' + json.clip_id + '.mp4'; | |
exec(combineCmd, (err, stdout, stderr) => { | |
if (err) { | |
exec('file ' + json.clip_id + '.m4v ' + json.clip_id + '.m4a', () => throw err); | |
} | |
console.log(`stdout: ${stdout}`); | |
console.log(`stderr: ${stderr}`); | |
console.log('removing video and audio in favor of combined version...'); | |
fs.unlink(json.clip_id + '.m4v', (err) => { | |
if (err) { | |
throw err; | |
} | |
fs.unlink(json.clip_id + '.m4a', (err) => { | |
if (err) { | |
throw err; | |
} | |
console.log('all done'); | |
}); | |
}); | |
}); | |
}); | |
}); | |
}); | |
function processFile(type, baseUrl, initData, segments, filename, cb) { | |
if (fs.existsSync(filename)) { | |
console.log(`${type} already exists`); | |
return cb(); | |
} | |
const segmentsUrl = segments.map((seg) => baseUrl + seg.url); | |
const initBuffer = Buffer.from(initData, 'base64'); | |
fs.writeFileSync(filename, initBuffer); | |
const output = fs.createWriteStream(filename, {flags: 'a'}); | |
combineSegments(type, 0, segmentsUrl, output, (err) => { | |
if (err) { | |
return cb(err); | |
} | |
output.end(); | |
cb(); | |
}); | |
} | |
function combineSegments(type, i, segmentsUrl, output, cb) { | |
if (i >= segmentsUrl.length) { | |
console.log(`${type} done`); | |
return cb(); | |
} | |
console.log(`Download ${type} segment ${i}`); | |
https.get(segmentsUrl[i], (res) => { | |
res.on('data', (d) => output.write(d)); | |
res.on('end', () => combineSegments(type, i+1, segmentsUrl, output, cb)); | |
}).on('error', (e) => { | |
cb(e); | |
}); | |
} | |
function getJson(url, cb) { | |
let data = ''; | |
https.get(url, (res) => { | |
res.on('data', (d) => data+= d); | |
res.on('end', () => cb(null, JSON.parse(data))); | |
}).on('error', (e) => { | |
cb(e); | |
}); | |
} |
Worked perfectly. Thanks!
It doesn't work with private videos though :(
Hello, I download the audio and the video well but I am having problems with ffmpeg, I installed on the macBook through homebrew and when launching the script it failed me. I am trying to mix .m4v and .m4a extension files. Do I need to install something else?
this is the version -> ffmpeg version 4.4 Copyright (c) 2000-2021 the FFmpeg developers
and this is the log:
combining video and audio...
/Users/cesarcf/vimeo/vimeo-downloader.js:44
throw err;
^
Error: Command failed: ffmpeg -i 95a3e237-4ea3-4acf-8fc2-ba0c1e12f711.m4v -i 95a3e237-4ea3-4acf-8fc2-ba0c1e12f711.m4a -c copy 95a3e237-4ea3-4acf-8fc2-ba0c1e12f711.mp4
ffmpeg version 4.4 Copyright (c) 2000-2021 the FFmpeg developers
built with Apple clang version 12.0.0 (clang-1200.0.32.29)
configuration: --prefix=/usr/local/Cellar/ffmpeg/4.4_2 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-avresample --enable-videotoolbox
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100
[m4v @ 0x7fa04d810400] Format m4v detected only with low score of 1, misdetection possible!
[mpeg4 @ 0x7fa04d000a00] only rectangular vol supported
[mpeg4 @ 0x7fa04d000a00] Marker bit missing at 8049 of 37593632 before time_increment_resolution
[mpeg4 @ 0x7fa04d000a00] Marker bit missing at 8066 of 37593632 before fixed_vop_rate
[mpeg4 @ 0x7fa04d000a00] Ignoring multiple VOL headers
Last message repeated 1 times
[mpeg4 @ 0x7fa04d000a00] Marker bit missing at 37593380 of 37593632 before time_increment
[mpeg4 @ 0x7fa04d000a00] only rectangular vol supported
[mpeg4 @ 0x7fa04d000a00] Marker bit missing at 8049 of 37593344 before time_increment_resolution
[mpeg4 @ 0x7fa04d000a00] Marker bit missing at 8066 of 37593344 before fixed_vop_rate
[mpeg4 @ 0x7fa04d000a00] Ignoring multiple VOL headers
Last message repeated 1 times
[mpeg4 @ 0x7fa04d000a00] only rectangular vol supported
[mpeg4 @ 0x7fa04d000a00] Marker bit missing at 8049 of 37593632 before time_increment_resolution
[mpeg4 @ 0x7fa04d000a00] Marker bit missing at 8066 of 37593632 before fixed_vop_rate
[mpeg4 @ 0x7fa04d000a00] Ignoring multiple VOL headers
Last message repeated 1 times
[mpeg4 @ 0x7fa04d000a00] Marker bit missing at 37593380 of 37593632 before time_increment
[mpeg4 @ 0x7fa04d000a00] Marker bit missing at 43 of 311566976 in gop_header
[mpeg4 @ 0x7fa04d000a00] only rectangular vol supported
[mpeg4 @ 0x7fa04d000a00] Marker bit missing at 50792585 of 311566976 before time_increment_resolution
[mpeg4 @ 0x7fa04d000a00] Marker bit missing at 50792602 of 311566976 before fixed_vop_rate
[mpeg4 @ 0x7fa04d000a00] Ignoring multiple VOL headers
Last message repeated 42 times
[mpeg4 @ 0x7fa04d000a00] Marker bit missing at 311566915 of 311566976 before time_increment
[mpeg4 @ 0x7fa04d000a00] time_increment_bits 10 is invalid in relation to the current bitstream, this is likely caused by a missing VOL header
[mpeg4 @ 0x7fa04d000a00] time_increment_bits set to 16 bits, based on bitstream analysis
[mpeg4 @ 0x7fa04d000a00] only rectangular vol supported
[mpeg4 @ 0x7fa04d000a00] Marker bit missing at 8049 of 37593344 before time_increment_resolution
[mpeg4 @ 0x7fa04d000a00] Marker bit missing at 8066 of 37593344 before fixed_vop_rate
[mpeg4 @ 0x7fa04d000a00] Ignoring multiple VOL headers
Last message repeated 1 times
[mpeg4 @ 0x7fa04d000a00] Marker bit missing at 43 of 311566976 in gop_header
[mpeg4 @ 0x7fa04d000a00] only rectangular vol supported
[mpeg4 @ 0x7fa04d000a00] Marker bit missing at 50792585 of 311566976 before time_increment_resolution
[mpeg4 @ 0x7fa04d000a00] Marker bit missing at 50792602 of 311566976 before fixed_vop_rate
[mpeg4 @ 0x7fa04d000a00] Ignoring multiple VOL headers
Last message repeated 42 times
[mpeg4 @ 0x7fa04d000a00] Marker bit missing at 311566915 of 311566976 before time_increment
[mpeg4 @ 0x7fa04d000a00] time_increment_bits 10 is invalid in relation to the current bitstream, this is likely caused by a missing VOL header
[mpeg4 @ 0x7fa04d000a00] time_increment_bits set to 16 bits, based on bitstream analysis
[m4v @ 0x7fa04d810400] Stream #0: not enough frames to estimate rate; consider increasing probesize
[m4v @ 0x7fa04d810400] decoding for stream 0 failed
[m4v @ 0x7fa04d810400] Could not find codec parameters for stream 0 (Video: mpeg4 (Main Profile), none): unspecified size
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
Input #0, m4v, from '95a3e237-4ea3-4acf-8fc2-ba0c1e12f711.m4v':
Duration: N/A, start: 1.875000, bitrate: N/A
Stream #0:0: Video: mpeg4 (Main Profile), none, 65536 tbr, 1200k tbn, 65536 tbc
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7fa04d819800] Format mov,mp4,m4a,3gp,3g2,mj2 detected only with low score of 1, misdetection possible!
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7fa04d819800] moov atom not found
95a3e237-4ea3-4acf-8fc2-ba0c1e12f711.m4a: Invalid data found when processing input
at ChildProcess.exithandler (child_process.js:303:12)
at ChildProcess.emit (events.js:315:20)
at maybeClose (internal/child_process.js:1021:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5) {
killed: false,
code: 1,
signal: null,
cmd: 'ffmpeg -i 95a3e237-4ea3-4acf-8fc2-ba0c1e12f711.m4v -i 95a3e237-4ea3-4acf-8fc2-ba0c1e12f711.m4a -c copy 95a3e237-4ea3-4acf-8fc2-ba0c1e12f711.mp4'
}
@alexdrean can you help me with this?
same error!
Unfortunately I do not have the time to look into this right now. You may try combining video and audio externally, or search ffmpeg forums about this. It seems like the downloaded content is not in .m4v format. I would suggest replacing every instance of ".mp4" with other common video file extensions and see if you can find the correct one. You could also analyze the downloaded video-only with the file
command and deduct the correct extension that way. I've updated the script so it does that automatically in case ffmpeg crashes. This should help you figure out what is happening here.
Hi folks, not a very experienced one. Where am Im supposed to input the master.json url? Also it will work just running the script in visual studio code or is it necessary to set up a project in a dedicated IDE?
Works great , but I'm downloading on low quality video , as @jangxx suggested .
const videoData = json.video.find(v => v.height == 360); // or 1080, or something else