-
-
Save iluxonchik/e6c9902cc67a13d128e0a8817b6f9069 to your computer and use it in GitHub Desktop.
""" | |
For my Neuroengineering course presentation my group wanted to download some videos, | |
the problem is that those videos were played by the JWPlayer, so obtaining the video | |
files was a little tricky. What I noticed from observing the network traffic is that | |
JWPlayer downloads the video files in chunks (each chunk was 4 seconds long) and | |
in .ts format. My goal was to combine all of those small video segments into a single | |
one and then convert the file to .mp4. To combine the multiple video chunks into one | |
I used the "cat" command and to convert resulting .ts file to .mp4 I used the "ffmpeg" | |
tool. | |
This tool is purpose-specific, so you'll need to adapt it for your own case. We were | |
in a hurry and this a script that I quickly put up so that we could proceed with work. | |
I'm leaving this here in case someone else encounters a similar task, you can use | |
this file as a guide. | |
Tested only on Linux, but should work just fine on OSX. Might need adaptations for Windows. | |
Requirements: | |
* Python 3.x | |
* "ffmpeg" command-line tool. | |
""" | |
import sys | |
import urllib.request | |
from os import system, remove | |
# used to generate the correct file names, so that they | |
# can be downloaded. This was purpuse-specific, so you might | |
# wanna change that. | |
index_begin = int(sys.argv[1]) | |
index_end = int(sys.argv[2]) | |
out_file_name = sys.argv[3] | |
url = 'http://videos-f.jwpsrv.com/content/conversions/24tOJIfp/videos/vWqXqYoa-29646386.mp4-{}.ts' | |
file_name = 'vWqXqYoa-29646386.mp4-{}.ts' | |
file_names = [] | |
for i in range(index_begin, index_end + 1): | |
curr_file_name = file_name.format(i) | |
curr_url = url.format(i) | |
file_names += [curr_file_name] | |
print('Downloading {}'.format(curr_url)) | |
urllib.request.urlretrieve(curr_url, curr_file_name) | |
print('All files downloaded') | |
print('Joining into a single .ts file...') | |
command = '' | |
for file_name in file_names: | |
command += '{} '.format(file_name) | |
command = 'cat ' + command + '> {}'.format(out_file_name + '.ts') | |
system(command) | |
system('ffmpeg -i {}.ts -acodec copy -vcodec copy {}.mp4'.format(out_file_name, out_file_name)) | |
print('Clenaing up...') | |
for file_name in file_names: | |
remove(file_name) | |
remove('{}.ts'.format(out_file_name)) | |
print('Done!') |
This worked when everything else failed, thank you.
Usage : Change your specific url in the url / file_name variables You need to find the count of ts files that cover the full length, in my case it was ~250 chunks for ~50 minutes (~5 chunks / minute)
python jwplayer_downloader.py 1 200 out
will download it intoout.mp4
from ts chunk 1 up to 200, adjust those numbers according to the video segment you are interested in.
no problem :) glad it helped out somebody else 😄
Thanks for the script. To save some others some time, you can tweak the loop logic like this
i = 0
while True:
curr_file_name = file_name.format(i)
curr_url = url.format(i)
file_names += [curr_file_name]
print('Downloading {}'.format(curr_url))
try:
urllib.request.urlretrieve(curr_url, curr_file_name)
i = i+1
except:
file_names.pop()
break
then it will just start at part 0 and stop downloading the moment it hits the first 404, so you don't need to figure out what the last part number is
Thanks for that ! Worked like a charm.
In a similar vein, I had a video that was sparsely populated, so it would go 1, 5, 6, 10, 11, 12, 13, 15 etc. And sometimes the files were there but unplayable (They were less than 1kb), So I made this modification:
i = 0
failcount = 0
failmax = 10
fileminsizeb = 2048
while True:
curr_file_name = file_name.format(i)
curr_url = url.format(i)
file_names += [curr_file_name]
print('Downloading {}:'.format(curr_file_name), end="")
try:
urllib.request.urlretrieve(curr_url, curr_file_name)
except:
print(" error downloading.", end="")
file_names.pop()
i = i+1
failcount = failcount + 1
print("")
if (failcount > failmax):
break
continue
try:
if( os.path.getsize(curr_file_name) < fileminsizeb ):
print(f" File too small { os.path.getsize(curr_file_name) }", end = "")
os.remove(curr_file_name)
i = i+1
failcount = failcount + 1
print("")
if (failcount > failmax):
break
continue
except:
print(f" Error resolving local path {curr_file_name}", end="")
i = i+1
failcount = 0
print(" Success")
This worked when everything else failed, thank you.
Usage :
Change your specific url in the url / file_name variables
You need to find the count of ts files that cover the full length, in my case it was ~250 chunks for ~50 minutes (~5 chunks / minute)
python jwplayer_downloader.py 1 200 out
will download it intoout.mp4
from ts chunk 1 up to 200, adjust those numbers according to the video segment you are interested in.