Last active
July 14, 2021 12:07
-
-
Save blurgyy/5ac9ec87645684be0a37d95ab4d733cf to your computer and use it in GitHub Desktop.
Shell script to convert m3u8 playlist(s) to mp4 video(s) with ffmpeg.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # Convert m3u8 playlist(s) to mp4 video(s) with ffmpeg. | |
| # | |
| # Usage: | |
| # | |
| # m3u82mp4.sh -i <input_url> [-i <more_input_urls>] [-d <output_dir>] | |
| # | |
| # Example: | |
| # | |
| # $0 -d /tmp/cat-video \ | |
| # -i /path/to/playlist.m3u8 \ | |
| # -i https://link.to/playlist.m3u8 | |
| # | |
| # Upon successful execution, the above example will generate two videos | |
| # in the directory "/tmp/cat-video": | |
| # | |
| # 1. /tmp/cat-video/%path%to%playlist.m3u8.mp4 | |
| # 2. /tmp/cat-video/https:%%link.to%playlist.m3u8.mp4 | |
| # | |
| # Additional information: | |
| # | |
| # 1. Conversion will occur in the background. Log files, output video | |
| # files, process pids will be saved to a file ".m3u82mp4.summary" in | |
| # the working directory where the script is executed. | |
| # 2. Existing files will not be overwritten. | |
| set -Eeuo pipefail | |
| declare -a input_paths | |
| has_input=0 | |
| log_dir=~/.local/share/m3u82mp4 | |
| output_dir="$PWD" | |
| summary_file="$PWD"/.m3u82mp4.summary | |
| function playlist-to-mp4() { | |
| input_url=$1 | |
| if [[ -e "$input_url" ]]; then | |
| input_url=$(realpath "$input_url") | |
| fi | |
| output_path=${input_url// /%} | |
| output_path=${output_path//\//%} | |
| output_path="$output_path".mp4 | |
| output_path="$output_dir/$output_path" | |
| log_path="$input_url" | |
| log_path=${log_path// /%} | |
| log_path=${log_path//\//%} | |
| log_path="$log_dir/$log_path" | |
| ffmpeg >"$log_path" 2>&1 \ | |
| -protocol_whitelist tcp,file,https,crypto,tls,httpproxy \ | |
| -i "$input_url" \ | |
| -bsf:a aac_adtstoasc -vcodec copy -c copy \ | |
| "$output_path" -n & | |
| tee -a "$summary_file" <<EOF | |
| Conversion started .. | |
| input: $input_url | |
| log file: $log_path | |
| output video file: $output_path | |
| pid: $(lsof -Fp "$log_path" | sed 's/p//') | |
| EOF | |
| } | |
| function show-help() { | |
| cat <<EOF | |
| Usage: | |
| $0 -i <input_url> [-i <more_input_urls>] [-d <output_dir>] | |
| Example: | |
| $0 -d /tmp/cat-video \\ | |
| -i /path/to/playlist.m3u8 \\ | |
| -i https://link.to/playlist.m3u8 | |
| Upon successful execution, the above example will generate two videos | |
| in the directory "/tmp/cat-video": | |
| 1. /tmp/cat-video/%path%to%playlist.m3u8.mp4 | |
| 2. /tmp/cat-video/https:%%link.to%playlist.m3u8.mp4 | |
| Additional information: | |
| Conversion will occur in the background. Log files, output video | |
| files, process pids will be saved to a file ".m3u82mp4.summary" in the | |
| working directory where the script is executed. | |
| EOF | |
| } | |
| while getopts "d:i:" optvar; do | |
| case "$optvar" in | |
| d) output_dir="$OPTARG" ;; | |
| i) | |
| has_input=1 | |
| input_paths=("${input_paths[@]}" "$OPTARG") | |
| ;; | |
| *) show-help "$@" ;; | |
| esac | |
| done | |
| shift $((OPTIND - 1)) | |
| if [[ "$has_input" == 0 ]]; then | |
| show-help | |
| builtin exit 1 | |
| fi | |
| mkdir -p "$log_dir" "$output_dir" | |
| for input in "${input_paths[@]}"; do | |
| playlist-to-mp4 "$input" | |
| done | |
| if [[ -f $summary_file ]]; then | |
| echo >&2 "stdout has been saved to $summary_file" | |
| fi | |
| # Author: Blurgy <[email protected]> | |
| # Date: Jul 10 2021, 20:47 [CST] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment