unix4artists/stream/capture.sh

111 lines
2.9 KiB
Bash

#!/bin/bash
#################################
#
# From https://gist.github.com/sixteenmillimeter/d6443c6b18a7d143b3695dd9d79c3c22
#
# Instructions
#
# First, install ffmpeg and youtube-dl
#
# https://ffmpeg.org/download.html
# https://ytdl-org.github.io/youtube-dl/download.html
#
# To capture a stream at https://yoururl and save to a dated, named TS file:
#
# bash capture.sh https://yoururl streamfilename
#
# Will create file streamfile_STARTDATE.ts and streamfilename.txt containing stream metadata.
#
# To capture stream and convert to an MKV file after:
#
# bash capture.sh https://streamurl streamfilename "convert"
#
# Will create TS file and streamfile_STARTDATE_to_FINISHDATE.mkv after capture complete.
#
# Note: Since this is capturing from a M3U8 stream you may end up retrieving more of earlier
# parts of the stream than the metadata will indicate. This will depend on the service
# you are capturing from.
#
#################################
THREADS="1" #set number of threads for process or comment out to utilize 100% of CPU
QUALITY=-1 #-2 for second best, -1 for best
INPUT="${1}"
OUTPUT="${2}" # filepath without extension
if [ "${OUTPUT}" == "" ]; then
OUTPUT=`basename "${INPUT}"`
fi
if [ "${THREADS}" == "" ]; then
THREADS_ARG=""
else
THREADS_ARG="-threads ${THREADS}"
fi
METADATA="${OUTPUT}.txt"
FORMATS=`mktemp`
# Show the available streams using youtube-dl
youtube-dl --list-formats "${INPUT}" > "${FORMATS}"
FORMAT_FULL=`tail ${QUALITY} "${FORMATS}" | head -1`
FORMAT=`echo "${FORMAT_FULL}" | awk -F" " '{print $1}'`
M3U8=`youtube-dl -f "${FORMAT}" -g "${INPUT}"`
STARTED=`date "+%F-%T-%Z"`
OUTPUT_TS="${OUTPUT}_${STARTED}.ts"
echo "Stream: ${INPUT}"
echo "Format: ${FORMAT_FULL}"
echo "Output: ${OUTPUT_TS}"
if [ -f "${METADATA}" ]; then
echo " " >> "${METADATA}"
else
echo "==========================" > "${METADATA}"
echo " " >> "${METADATA}"
fi
echo "Stream : ${INPUT}" >> "${METADATA}"
echo "M3U8 : ${M3U8}" >> "${METADATA}"
echo "Format : ${FORMAT_FULL}" >> "${METADATA}"
echo "Output : ${OUTPUT_TS}" >> "${METADATA}"
echo "Started : ${STARTED}" >> "${METADATA}"
echo "Starting capture, press 'q' to finish"
# capture with no console output
ffmpeg -i "${M3U8}" \
-loglevel warning \
-hide_banner ${THREADS_ARG} \
-c copy \
"${OUTPUT_TS}"
FINISHED=`date "+%F-%T-%Z"`
echo "Finished capturing at ${FINISHED}"
echo "Finished : ${FINISHED}" >> "${METADATA}"
if [ "${3}" == "convert" ]; then
OUTPUT_MKV="${OUTPUT}_${STARTED}_to_${FINISHED}.mkv"
echo "Creating MKV file ${OUTPUT_MKV}..."
# put video in an MKV wrapper as is (not really a conversion)
ffmpeg -i "${OUTPUT_TS}" \
-loglevel warning \
-hide_banner ${THREADS_ARG} \
-map 0 \
-c copy \
"${OUTPUT_MKV}"
echo "Created ${OUTPUT_MKV}"
echo "MKV : ${OUTPUT_MKV}" >> "${METADATA}"
fi
echo " " >> "${METADATA}"
echo "==========================" >> "${METADATA}"
echo "Cleaning up..."
# cleanup
rm -f "${FORMATS}"
echo "Completed capturing ${INPUT}"