This article is oriented for newbies. I want to learn you a bit how to code things like downloaders from video hosting providers. Of course you could use ready-made libraries to solve that task and that is prefect solution. However, if you prefer to learn how to do it by yourself let’s go under cut and learn how to download Vimeo video using Python!
A bit of back-story
So, I could name this article how to download Vimeo video using NodeJS or something else. In general that doesn’t matter.
I’ll split article on logic based part to make reading it more comfort. Let’s go forward.
I made this post and this code for learning purpose. I don’t recommend it for commercial use. I’m not responsible for any damage caused by this code. Please, don’t lawlessly use this code and avoid any kind of illegal activities.
Setup empty project
This part is not related to article theme. In general you need to just create main.py file and use locally installed Python. I am planing to use version 3.10, but I guess my code will be work fine in versions like 3.9, 3.7, etc.
When you watching video in the browser everything is going automatically. Browser execute page code and starting downloading the video. When there is enough data for showing video you could press play and browser will start playing video.
We need to do the same. I mean find out where is video file URL and then download it.
Getting video ID
Let’s take some video for example. I took this one absolutely randomly. It’s looks strange, but we don’t need to care about content.
Our first goal to take ID of the video. Those numbers in the end of video URL is video ID. So let’s scrape them to separate variable.
# set target video url target_video_url = 'https://vimeo.com/712159936' # remove slash from the end of the url if target_video_url[-1] == '/': target_video_url = target_video_url[:-1] # get video id from url video_id = target_video_url.split('/')[-1] # check the result print(video_id)
Let me explain a bit. To get video ID we used split function. This function make array from string by splitting it by some char. To be sure where isn’t slash in the end of URL I added additional check. If we remove that check and use split function then result will be different.
Getting project JSON config
What is next step? I’ll show you a bit. Open Vimeo website and then open web inspector in your browser. I am using Safari so for me it’s Option + CMD + I shortcut. After go to Network tab and chose XHR/Fetch or similar. This tab showing all request which browser sends for this page. So now reload the page and get the results.
You should see there request named “config”. This is what we are looking for.
The server respond with JSON data. And that JSON data contains real URL for video file. Do you know what that means? I want to say, if we get real video URL then we could easy download it. Thats why we need to get project config to download Vimeo video using Python.
If you open Headers tab (might be different in your browser) for this request, you could see which request type (GET) and which URL we need.
Let’s write code for downloading Vimeo video config. I would like to use requests library. You could install it with pip via command:
pip install requests.
# set video config url video_config_url = 'https://player.vimeo.com/video/' + video_id + '/config' # send get request to get video json config video_config_response = requests.get(video_config_url) # generate obj from json video_config_json = video_config_response.json() # check the result print(video_config_json)
I run this code and got following result. Looks like everything is works OK.
Download Vimeo video using Python
We are interested in field
video_config_json['request']['files']['progressive']. It contains some URL for different quality.
Let’s ignore quality choosing for now and just download first available one.
# make variable for video config video_config = video_config_json['request']['files']['progressive'] # get video url video_url = video_config['url'] # prepare file name for that video video_name = video_id + '_' + video_config['quality'] + '.mp4' # download video video_response = requests.get(video_url) # open file and write content there video_file = open(video_name, 'wb') video_file.write(video_response.content) video_file.close() # print result print('downloaded: ' + video_name)
It works! You can check it by yourself.
Okay, but what if I need specific quality of the video? Let’s make quality selection. For example, let’s say we need Vimeo video with height near 480px. Usually you can hear “video with 480p quality”. Maybe you saw, there is fields width and height. So you can just compare videos quality and select required one. However, what if there isn’t required quality?
Let’s make code for selection video with closest height of our goal.
# target video height target_video_height = 480 # video config target_video_config = None # check all video find the closest one for video_config in video_config_json['request']['files']['progressive']: # skip first video if (target_video_config is None): target_video_config = video_config continue # get video height video_height = video_config['height'] # check video height video_height_diff = abs(target_video_height - video_height) target_video_height_diff = abs(target_video_height - target_video_config['height']) # check video height diff if video_height_diff < target_video_height_diff: target_video_config = video_config
Maybe code looks long, however it pretty simple. We are going in the loop for each video config. If target video config is None then we just set
target_video_config to current video config. So first iteration is always the same.
In next loop iteration we calculate difference in pixels between target video height and our results. The function abs used for make number always positive.
If current video diff less than target, current become target.
After the loop ends we get the closest video height to our target.
After whole code was ready I made refactoring. You could download whole code from my GitHub.
As you can see the task is pretty easy, but if you still have questions let me know.
Also, please, let me know if you see any errors in my code or text. English is not my native language, so I could do a lot of typos, mistakes, etc.
Don’t forget to write a thankful comment if my post help you to learn something 🙂