Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
The right Python method depends on what the URL returns and what you need to produce. Save a direct media response with requests; open a camera or network stream with OpenCV when you need individual frames; use FFmpeg when you need remuxing, stream copying, transcoding, or adaptive-playlist handling. A URL that opens a video player in a browser is often only a webpage, not the media endpoint itself.
Identify the URL before writing code
Test the address conceptually before choosing a library. A direct media URL usually returns bytes with a media content type such as video/mp4, while a streaming endpoint may return an HLS playlist (.m3u8), MPEG-DASH manifest (.mpd), or an IP-camera protocol. A normal page URL returns HTML and JavaScript that later discover the media URL.
- Need a file containing the server response? Use Requests with streaming enabled.
- Need frames for computer vision or analysis? Use OpenCV
VideoCapture. - Need to copy, remux, filter, or transcode media? Use FFmpeg, called directly or through Python.
Use your browser’s developer tools only to locate a media request you are authorized to access. Do not bypass access controls, DRM, paywalls, or a site’s terms. Authentication cookies, bearer tokens, signed URLs, and referrer requirements must come from the service’s documented access method.
Save a direct HTTP video response with Requests
Requests’ streaming pattern downloads incrementally instead of loading a large response into memory. The code checks the HTTP status, applies a connect/read timeout, writes binary chunks, and closes both resources reliably.
#1 Best Overall
- Includes Raspberry Pi 5 with 2.4Ghz 64-bit quad-core CPU (8GB RAM)
- Includes 128GB Micro SD Card pre-loaded with 64-bit Raspberry Pi OS, USB MicroSD Card Reader
- CanaKit Turbine Black Case for the Raspberry Pi 5
- CanaKit Low Noise Bearing System Fan
- Mega Heat Sink - Black Anodized
import requests
url = "https://example.com/video.mp4"
with requests.get(url, stream=True, timeout=(5, 30)) as response:
response.raise_for_status()
with open("video.mp4", "wb") as output:
for chunk in response.iter_content(chunk_size=1024 * 1024):
if chunk: # ignore keep-alive chunks
output.write(chunk)
print("Saved video.mp4")
The first timeout value limits how long connecting may wait; the second limits how long the connection may wait for a byte. It is not a maximum duration for the whole download. A slow, large file can therefore run longer than 30 seconds as long as data continues arriving. Requests has no default timeout, so setting one is important.
Add headers, cookies, or an authorization token
Some servers require a documented header or cookie. Supply only credentials you are allowed to use, and never print secrets in logs.
import os
import requests
url = "https://example.com/private/video.mp4"
headers = {
"Authorization": f"Bearer {os.environ['VIDEO_TOKEN']}",
"User-Agent": "my-video-client/1.0",
}
with requests.get(url, headers=headers, stream=True, timeout=(5, 30)) as response:
response.raise_for_status()
with open("private-video.mp4", "wb") as output:
for chunk in response.iter_content(1024 * 1024):
if chunk:
output.write(chunk)
If a browser succeeds but this request returns 403, compare the service’s documented authentication requirements rather than copying arbitrary browser headers. A signed URL may expire while your program is downloading; obtain a fresh one when the provider requires it.
Check what you actually downloaded
import requests
with requests.get("https://example.com/video.mp4", stream=True, timeout=(5, 30)) as response:
print(response.status_code)
print(response.headers.get("content-type"))
print(response.headers.get("content-length"))
response.raise_for_status()
with open("response.bin", "wb") as output:
for chunk in response.iter_content(1024 * 1024):
if chunk:
output.write(chunk)
A small file beginning with HTML is usually an error page or login page, not a video. A direct download also does not parse a playlist or combine adaptive-stream segments. If the response is an HLS or DASH manifest, pass that manifest to a media-aware tool instead.
Resume a failed download when the server supports ranges
HTTP range support is server-dependent. A safe resume implementation must append only after receiving a successful partial response; otherwise restart rather than corrupting the file.
Rank #2
- Includes Raspberry Pi 4 4GB Model B with 1.5GHz 64-bit quad-core CPU (4GB RAM)
- Includes Pre-Loaded 32GB EVO+ Micro SD Card (Class 10), USB MicroSD Card Reader
- CanaKit Premium High-Gloss Raspberry Pi 4 Case with Integrated Fan Mount, CanaKit Low Noise Bearing System Fan
- CanaKit 3.5A USB-C Raspberry Pi 4 Power Supply (US Plug) with Noise Filter, Set of Heat Sinks, Display Cable - 6 foot (Supports up to 4K60p)
- CanaKit USB-C PiSwitch (On/Off Power Switch for Raspberry Pi 4)
import os
import requests
url = "https://example.com/video.mp4"
path = "video.mp4"
start = os.path.getsize(path) if os.path.exists(path) else 0
headers = {"Range": f"bytes={start}-"} if start else {}
with requests.get(url, headers=headers, stream=True, timeout=(5, 30)) as response:
if start and response.status_code == 200:
# The server ignored Range; restart to avoid duplicate bytes.
start = 0
mode = "wb"
else:
response.raise_for_status()
mode = "ab" if start else "wb"
with open(path, mode) as output:
for chunk in response.iter_content(1024 * 1024):
if chunk:
output.write(chunk)
For production downloads, also verify the final size or a checksum supplied by the provider. If you stop reading a streamed response early, close it; a connection is not returned to Requests’ pool until the body is consumed or the response is closed.
Read frames with OpenCV
OpenCV’s VideoCapture can open a video file, capture device, or IP video stream. The URL scheme and backend depend on the source and on how OpenCV was built, so an isOpened() failure does not by itself prove that the URL is invalid.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →import cv2
url = "https://example.com/video.mp4"
cap = cv2.VideoCapture(url)
if not cap.isOpened():
raise RuntimeError("Could not open the stream with the available OpenCV backend")
try:
while True:
ok, frame = cap.read()
if not ok:
break
# Replace this with computer-vision work.
cv2.imshow("stream", frame)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
finally:
cap.release()
cv2.destroyAllWindows()
For a headless server, remove the display calls and process or encode frame instead. Always release the capture in a finally block. For a finite file, the loop ends at end-of-stream; for a live source, a failed read can mean disconnect, timeout, unsupported codec, or normal shutdown.
Write frames to a new video
import cv2
cap = cv2.VideoCapture("https://example.com/input.mp4")
if not cap.isOpened():
raise RuntimeError("Input could not be opened")
fps = cap.get(cv2.CAP_PROP_FPS)
if not fps or fps <= 0:
fps = 30.0
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
writer = cv2.VideoWriter(
"processed.mp4",
cv2.VideoWriter_fourcc(*"mp4v"),
fps,
(width, height),
)
try:
while True:
ok, frame = cap.read()
if not ok:
break
# Example processing point: frame = cv2.cvtColor(...)
writer.write(frame)
finally:
cap.release()
writer.release()
Codec availability varies by operating system and build. If the writer cannot open or the resulting file will not play, use FFmpeg for encoding rather than assuming a particular OpenCV codec is installed.
Use FFmpeg for playlists, remuxing, and transcoding
FFmpeg accepts an input URL after -i. For compatible input and output formats, stream copy avoids decoding and re-encoding:
Rank #3
- Not including the Raspberry Pi 5 (8GB), the Crowpi advanced version comes with the Raspberry Pi 5
- ELECROW Black Case for the Raspberry Pi 5, CrowPi is equipped with a 9-inch HD touchscreen along with a camera; All the regular components used in DIY electronics are packed into the CrowPi development board, such as LCD, LED matrix, buzzer, light sensor, PIR sensor, ultrasonic sensor, IR sensor, etc
- Raspberry Pi Sensors: The Crowpi raspberry pi 5 programming kit is jam-packed with lots of buttons such as 19 different sensors in a tidy easy to use package; You don't have to wait and wire things
- Build Quality: Solid ABS shell and well made components in one place make it strong and convenient to travel
- Programming Lessons: This raspberry pi 5 learning kit ships with step by step instructions and provides 21 lessons to take you through identifying components reading code and running it in the terminal
ffmpeg -i "https://example.com/video.mp4" -c copy output.mp4
Streamcopy copies packets without decoding, filtering, or encoding. It is fast and preserves the original compressed streams, but it works only when those streams are compatible with the output container. Choose a transcode when you need a different codec, filtering, scaling, or reliable compatibility.
Free tools Windows power users keep installed
One-click scans. No signup required.
ffmpeg -i "https://example.com/playlist.m3u8"
-c:v libx264 -c:a aac -movflags +faststart output.mp4
HTTP inputs may require seekability settings or custom request headers. Consult the source provider’s documentation for authentication and referer rules. For a Python program, pass an argument list to subprocess.run; do not concatenate an untrusted URL into a shell command.
import subprocess
url = "https://example.com/playlist.m3u8"
subprocess.run(
["ffmpeg", "-y", "-i", url, "-c", "copy", "capture.mkv"],
check=True,
)
Use capture.mkv when you want a flexible container for copied streams; select an output format appropriate to your players and downstream tools. FFmpeg is usually the practical choice for HLS or DASH because it understands manifests and segment sequencing, whereas Requests alone saves only the manifest text.
Choose the approach by outcome
| Goal | Best starting point | What it produces | Main limitation |
|---|---|---|---|
| Save one direct HTTP response | Requests with stream=True |
Exact response bytes in a file | Does not assemble adaptive playlists |
| Analyze each frame | OpenCV VideoCapture |
Decoded image arrays | Backend and codec support vary |
| Copy or remux compatible streams | FFmpeg with -c copy |
Media file without re-encoding | Container and codec compatibility required |
| Convert, filter, or scale | FFmpeg transcoding | Newly encoded media | Uses CPU and can reduce quality |
Or skip the browser setup
If your “video URL” is actually a webpage and your goal is a visual record of that page—not downloading or decoding the media—ScreenshotNeo provides a one-request screenshot API. It is not a replacement for an HLS downloader or frame reader, but it avoids browser automation when a page image is the output you need.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for all options. Before capture it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing result in X-Page-Verdict and X-Billed headers. Its MCP server gives Claude, Cursor, and other MCP clients take_screenshot, get_page_info, and capture_pdf tools. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchCreate a free ScreenshotNeo account to try the 1,000 monthly screenshots.
Rank #4
- Fully assembled for plug-and-play operation
- Includes Raspberry Pi 5 with 8GB RAM
- 256 GB PCIe Pi NVMe SSD (Pre-loaded with Pi 64-Bit OS)
- M.2 HAT+
- CanaKit Turbine Black Case for the Pi 5
Python implementation details that prevent failures
Keep memory bounded
Write chunks or process frames as they arrive. Never call response.content for an unexpectedly large response, and avoid retaining every OpenCV frame in a list.
Separate connect, read, and total-job policy
Requests’ timeout governs inactivity, not total job duration. If your application needs a wall-clock deadline, track elapsed time yourself and close the response when that deadline passes.
Protect secrets and subprocesses
Keep tokens in environment variables or a secret manager. Pass FFmpeg arguments as a list, validate allowed schemes such as HTTPS, and log status codes without logging authorization headers or signed URLs.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Plan for live-stream reconnection
A live stream can end or temporarily stop producing data. Surround capture with a bounded retry loop, reopen after a backoff, and avoid creating unlimited output files. For frame timestamps, use the source timestamps when available rather than assuming every read arrives at a perfect interval.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshooting
- 401 or 403: authentication, expiry, origin checks, or missing documented headers. Refresh credentials and confirm the permitted client requirements.
- 200 response but an unplayable file: inspect
Content-Typeand the first bytes. You may have saved HTML, JSON, or a playlist instead of media. - Requests download never finishes: the server may be delivering a live response. Use a deliberate stop condition, or use FFmpeg/OpenCV for live processing.
- OpenCV reports
isOpened() == False: try the correct backend, verify codec support in your build, and test the URL with FFmpeg. The URL scheme and backend must match the source. - OpenCV reads a few frames then stops: the source disconnected, ended, or returned data the backend cannot decode. Reconnect with a limit and inspect server logs.
- FFmpeg says “Invalid data found”: confirm that the URL is a reachable media file or manifest, not a login page, and provide required headers through FFmpeg’s supported options.
- Output is huge or CPU usage is high: use streamcopy where compatible; otherwise choose an appropriate resolution, frame rate, and codec rather than repeatedly re-encoding.
FAQ
Can I capture a video from a YouTube or other player page with Requests?
Usually not from the page URL alone. A player page is HTML and JavaScript; obtaining media may involve manifests, short-lived URLs, authentication, or restrictions. Use the service’s authorized API or documented download method.
Best Value
- 【What you Get】You will get 1*Pi 5 8GB Single Board,1*RasTech Case,1*Active Cooler,1*Screwdriver,1*Installation instructions,12-month free warranty, lifetime service, 24-hour prompt and friendly response.
- 【More Connectors】There are two USB 3.0 ports(5Gbps simultaneously) and two USB 2.0 ports, which triple total bandwidth ,support any combination of up to two cameras or displays. Peak SD card performance is doubled through support for the SDR104 high-speed mode. It provides a smooth desktop experience for you. Offer Gigabit Ethernet and a PCIe interface, along with dual-band Wi-Fi and Bluetooth 5.0/BLE wireless capability. The RasTech Pi 5 Kit use the new 27W 5.1V 5A USB-C power connector.
- 【 Support Dual 4Kp60 Display 】Each of the two microHDMI sockets can control a 4K display at 60 Hertz, now support HDR, offering super HD video for media streaming projects. RPi 5 is the first RPi model that comes with a PCI Express port (PCIe 2.0 x1 with 500 MB/s) to attach SSDs (requires separate M.2 HAT).
- 【 Excellent Chips And Applications】Pi 5 is a full-size Pi computer using silicon built in-house at Pi. The RP1 “southbridge” provides the bulk of the I/O capabilities for Pi 5. Pi 5 is more friendly and convenient in the development of Internet of Things, Web development, machine identification, automatic control and other electronic equipment applications and network.
- 【 Faster CPU, Better GPU 】 Pi 5 features a Broadcom BCM2712 64-bit quad-core Arm Cortex-A76 processor running at 2.4GHz, it delivers a 2–3× increase in CPU performance relative to RaspberryPi 4. The 800MHz VideoCore VII GPU is compatible to OpenGL ES 3.1 and Vulkan 1.2, substantial uplift in graphics performance. Pi 5 Offers lightning-fast CPU speed, a PCI Express interface, a Real Time Clock (RTC) and a power button and runs significantly cooler than Pi 4.
Should I use response.raw instead of iter_content()?
Use iter_content() for normal streamed downloads. Requests documents response.raw for cases where you specifically need the untransformed underlying bytes.
Is OpenCV a downloader?
It can read and decode supported sources, but it is primarily a frame-capture interface. If your deliverable is an untouched media file, Requests or FFmpeg is more direct.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Does a timeout guarantee the program ends after that many seconds?
No. It limits connection inactivity. Enforce a separate overall deadline when your application requires one.
Frequently Asked Questions
Which method should I choose for an HLS .m3u8 URL?
Start with FFmpeg because it can parse the playlist and sequence its segments. Requests alone saves the playlist response, not the assembled video.
Can I process frames without displaying a window?
Yes. Read frames with OpenCV and send them directly to your analysis or encoding pipeline; omit GUI calls such as imshow and waitKey.
How do I know whether a URL is a webpage or media endpoint?
Inspect the response status, content type, size, and initial bytes. HTML or JSON indicates a page or API response; a media content type or recognized manifest indicates a media endpoint.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

