Toxteth
Active member
I thought I'd expand a little on what I meant. I'm sure there are easier ones, but this one works for me. I arrived at this after some abortive starts with various download software, so I ended up using FFmpeg in the terminal on my Mac, and then writing a script to make that easier.Thank you Toxteth, I'll definitely look into it.There are usually ways around that. Either dive into the page source and find a link to the MP4 directly, or if they serve an M3U8 file, install FFmpeg and (after some frustration trying to discover/google the command line options you need) feed the URL of the M3U8 to that and it will download the video plus convert it to whatever format and/or dimensions you want. I've not come across many sites on which you can't download at all. There have been one or two on which I couldn't find a way, but >99% will work with one of these methods.
Preparation
What you need is the following:- FFmpeg, which is a program that can do just about everything you want with video files short of playing them.
- Python, a programming language.
Next, copy this script (select it and then click on the Edit menu and Copy):
Code:
#! /usr/bin/env python3 # You may need to adjust this to match the python executable on your computer -- such as plain `python' instead of `python3'
# -*- coding: utf-8 -*-
import argparse, os, sys
parser = argparse.ArgumentParser(description='Downloads a stream to an mp4 file')
parser.add_argument("-a", metavar="NAME", action="append", help="Name of an actor; will be added after scene number; can be specified more than once")
parser.add_argument("-b", metavar="[[hh:]mm:]ss", help="Time in stream at which to begin download (defaults to 00:00:00)")
parser.add_argument("-d", action="store_true", default=False, help="Dry run -- don't actually download anything but print the command that would be sent to ffmpeg")
parser.add_argument("-e", metavar="[[hh:]mm:]ss", help="Time in stream at which to end download (defaults to end of video)")
parser.add_argument("-n", type=int, metavar="NUMBER", help="Number of desired stream in the M3U8 file (first is 0)")
parser.add_argument("-s", type=int, metavar="NUMBER", help="Scene number; will be added after filename")
parser.add_argument("-p", metavar="NAME", help="Name of publisher/studio/etc.; will be added after name of actors")
parser.add_argument("-x", metavar="[.]EXTENSION", default="mp4", help="Extension for desired type of file for output (default: mp4); see FFmpeg documentation for which is which")
parser.add_argument("-y", metavar="YEAR", help="Year in which video was released; will be added at end of filename")
parser.add_argument("url", help="URL of stream to download")
parser.add_argument("file", help="name of file to output")
def secondsToTime(seconds):
"""Converts a number of seconds to [hh:]mm:ss."""
if seconds > 3600:
hours = seconds // 3600 # // is int(/)
seconds = seconds % 3600
minutes = seconds // 60
seconds = seconds % 60
return "{0}:{1}:{2}".format(hours, minutes, seconds)
elif seconds > 60:
minutes = seconds // 60
seconds = seconds % 60
return "{0}:{1}".format(minutes, seconds)
else:
minutes = 0
return "0:{0}".format(seconds)
if len(sys.argv) == 1:
sys.argv.append("-h")
args = parser.parse_args()
ffmpeg = "ffmpeg"
if args.b: # Time of beginning of download
if ":" in args.b:
beginTime = args.b
else:
beginTime = secondsToTime(int(args.b))
ffmpeg += " -ss " + beginTime
if args.e: # Time of end of download
if ":" in args.e:
endTime = args.e
else:
endTime = secondsToTime(int(args.e))
ffmpeg += " -to " + endTime
ffmpeg += " -i \"" + args.url + "\"" # URL of m3u8 file
if args.n: # Number of stream in m3u8 file
ffmpeg += " -map p:" + str(args.n)
ffmpeg += " -c copy \"" + args.file # Local filename
if args.s: # Number of scene in movie
ffmpeg += " scene " + str(args.s)
if args.a: # Names of actors
actors = " & ".join(args.a)
actors = actors.replace(" & ", ", ", actors.count(" & ") - 1)
ffmpeg += " (" + actors + ")"
if args.p or args.y: # Name of publisher/studio and Year in which movie was released
t = []
if args.p:
t.append(str(args.p))
if args.y:
t.append(str(args.y))
if len(t):
ffmpeg += " [" + ", ".join(t) + "]"
if args.x[0] != ".": # Make sure there's a dot before the file extension
ffmpeg += "."
ffmpeg += args.x + "\"" # File extension
if args.d:
print(ffmpeg)
else:
os.system(ffmpeg) # Let's download!
Open a text editor, like Windows Notepad or macOS Text Edit and paste the script into an empty document. Save it as a plain text file (this is important) with any name you like — I called it
mp4download.py. On a Linux box or a Mac, you will want to make the saved file executable with the terminal command chmod +x /path/to/mp4download.py — in which, of course, you replace "/path/to/mp4download.py" with the actual path and filename to the file you saved.You only need to do the above once. When it's done, you can use the script to download pretty much any stream you like.