123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- #!/bin/bash
- #
- # #####################################################
- # QsYouTubeTrailerScraper - QYTTS - v0.25
- # #####################################################
- #
- # This script will scrape your Kodi library for movie titles, then search
- # YouTube for it's trailer. It'll download the trailers to a specified
- # directory, which is used by the Cinema Experience script for Kodi to
- # load trailers. This way you can see the trailers for films you own,
- # withought having to dea with all the buffering that comes from streaming.
- #
- # I know there are other tools out there to get trailers for your library,
- # but most were windows based. The ones that weren't would just grab trailers
- # for any film, whether you have it or not.
- #
- # This was designed for my original Raspberry Pi Model B, running OSMC.
- # As such, it'll probably run on any Linux Kodi setup.
- #
- #
- # Please see the included README.md file for more information
- #
- #
- #
- # Copyright © 2015 Category <categoryNOSPAM@quintendo.uk>
- # This work is free. You can redistribute it and/or modify it under the
- # terms of the Do What The Fuck You Want To Public License, Version 2,
- # as published by Sam Hocevar. See the COPYING file for more details.
- #################
- # #
- # CONFIGURATION #
- # #
- #################
- ###
- # REQUIRED
- ###
- # Update the below before using, if this default doesn't match your storage plans
- ts_trailerdir="$HOME/Trailers/"
- # Location to save trailers, with trailing slash
- ###
- # OPTIONAL
- ###
- ts_databasedir="$HOME/.kodi/userdata/Database/"
- # Location of your Kodi database directory, normally "$HOME/.kodi/userdata/Database/"
- ts_tempdir="/tmp/"
- # Location to store temporary woking files, with trailing slash
- ts_maxsize=52428800
- # Maximum filesize of Trailers in bytes (to prevent full films being saved as trailers)
- # Default 50MB is 52428800
- ts_fix_dependencies=false
- # Option to fix dependencies if they are missing - script may ask for sudo password,
- # and install files to /usr/bin, or via apt-get
- # Default is false, for safety
- #############
- ### ###
- # # FUNCTIONS # #
- ### ###
- #############
- function trailer_dl {
- # Clear temp files/variable
- cat /dev/null > $ts_tempdir"YTSearchList"
- cat /dev/null > $ts_tempdir"TopResult"
- cat /dev/null > $ts_tempdir"YTDLErrors"
- YTCode=""
-
- # Prepare search target
- # Convert passed film name to the format "Film+Name+trailer", to pipe into the YouTube search URL
- YTTarget=${1// /+}+"trailer"
- # Prepare new filename
- YTNewName=$1" [Trailer].mp4"
-
- # Check if local trailer already exists
- # -e returns positive if file of the new name already exists
- if [ -e $ts_trailerdir"$YTNewName" ]
- then
- # File exists
- echo Trailer for $1 already exists, skipping download
- return
- else
- # No file found
- echo Searching YouTube for $1 trailer
-
- # Scrape top result from YouTube search
- # The process is as follows:-
- # 1. curl downloads html of the results page, after searching for the "Film+Name+trailer"
- # 2. grep returns any section containing 'videoId":' and the following code. -o to return just the search term, and not the entire line as the current YouTube results page is quite obfuscated and very few lines, all exceedingly long
- # 3. sed strips away the cruft, leaving just the YouTube videoId string
- # 4. List of all codes is piped to the "YTSearchList" temp file
- # 5. head saves the first result to "TopResult" temp file - the first videoId in a YouTube results page is always the top search result
- curl -s https://www.youtube.com/results\?search_query\=$YTTarget | grep -o videoId\"\:............ | sed 's/videoId\"\:\"//' > $ts_tempdir"YTSearchList"
- head -n 1 $ts_tempdir"YTSearchList" > $ts_tempdir"TopResult"
-
- # Extract YouTube ID from TopResult
- YTCode=$(cat $ts_tempdir"TopResult")
- echo YouTube ID: $YTCode
-
- # Check if first result is a trailer
- # youtube-dl with -e returns the title of the video store as YTTitle
- YTTitle=$(youtube-dl -e "https://www.youtube.com/watch?v=$YTCode" 2> $ts_tempdir"YTDLErrors")
- # Skip film if error encountered extracting title
- if [ $(cat $ts_tempdir"YTDLErrors" | grep ERROR | wc -l) -gt 0 ]
- then
- echo youtube-dl encountered an error, skipping film
- LogFailure "[youtube-dl error] |"
- return
- fi
-
- # If the title doesn't include the word "trailer" it is disregarded
- if [ $(echo $YTTitle | grep -i trailer | wc -l) = 1 ]
- then
- echo First result is a trailer, proceeding
- echo Downloading trailer for $1
- # Breakdown of the download request:-
- # -q - Quiet to suppress
- # --id - Use the videoId as filename
- # -f best - Save highest quality as .mp4 file
- # Uses the full url in quotes, to hopefully avoid issues where videoId includes punctuation
- # 2> to pipe all error output into "YTDLErrors" temp file
- youtube-dl -q --id -f best "https://www.youtube.com/watch?v=$YTCode" 2> $ts_tempdir"YTDLErrors"
-
- # Check to see if any of the error log contains the "ERROR" keyword - if so consider it a failure and move on
- if [ $(cat $ts_tempdir"YTDLErrors" | grep ERROR | wc -l) -gt 0 ]
- then
- echo youtube-dl encountered an error, skipping film
- LogFailure "[youtube-dl error] |"
- return
- else
- # Store downloaded filename based on videoId
- YTFileName=$YTCode.mp4
-
- # Store filesize of trailer
- YTFileSize=$(wc -c <"$YTFileName")
-
- # Check filesize against user-set max size
- # If too large, delete
- # If not, move to the trailer directory in the form "Film Name [Trailer].mp4"
- if [ $YTFileSize -gt $ts_maxsize ]
- then
- echo File too large, removing
- rm "./$YTFileName"
- LogFailure "[filesize too large] |"
- return
- else
- mv "./$YTFileName" $ts_trailerdir"$YTNewName"
- echo Saved as $YTNewName
- fi
- fi
- else
- echo Top YouTube result is not a trailer, skipping download
- LogFailure "[No trailer found] |"
- return
- fi
- fi
- }
- function LogFailure {
- # Count how many downloads failed
- let FailedDL=$FailedDL+1
- # Store failure reason & film name to temp file
- echo "$1 $ScanFilm" >> $ts_tempdir"FailedFilms"
- }
- # ################ #
- # ### ### #
- ###### # SCRIPT START # ######
- # ### ### #
- # ################ #
- echo QsYouTubeTrailerScraper - QYTTS
- echo v0.25- 2020-11-15
- echo
- #########################
- # #
- # Test for dependencies #
- # #
- #########################
- if [ $(which youtube-dl) ]
- then
- echo youtube-dl found
- if [ $(which sqlite3) ]
- then
- echo SQLite3 found
- echo Dependencies met, continuing...
- else
- if [ "$ts_fix_dependencies" = true ]
- then
- echo Attempting to install SQLite3
- echo sudo password may be requested
- sudo apt-get update -y
- sudo apt-get install sqlite3 -y
- if [ $? = 0 ]
- then
- echo Successfully installed SQLite3
- else
- echo Something has gone wrong, please install SQLite3 manually \(see README\)
- exit
- fi
- else
- echo SQLite3 not installed, please see README
- exit
- fi
- fi
- else
- if [ "$ts_fix_dependencies" = true ]
- then
- echo Attempting to install youtube-dl
- echo sudo password may be requested
- sudo curl https://yt-dl.org/latest/youtube-dl -o /usr/local/bin/youtube-dl ; sudo chmod a+rx /usr/local/bin/youtube-dl
- if [ $? = 0 ]
- then
- echo Successfully installed youtube-dl
- else
- echo Something has gone wrong, please install youtube-dl manually \(see README\)
- exit
- fi
- else
- echo youtube-dl not installed, please see README
- exit
- fi
- fi
- ##############
- # #
- # Initialize #
- # #
- ##############
- echo Initializing...
- # Create clean temp files
- cat /dev/null > $ts_tempdir"CurrentMovie"
- cat /dev/null > $ts_tempdir"MovieList"
- cat /dev/null > $ts_tempdir"YTSearchList"
- cat /dev/null > $ts_tempdir"TopResult"
- cat /dev/null > $ts_tempdir"FailedFilms"
- cat /dev/null > $ts_tempdir"YTDLErrors"
- FailedDL=0
- # Log start directory, then move to temp folder ready to download
- StartDir=$(pwd)
- cd $ts_tempdir
- # Create trailer directory if it doesn't exist
- if [ ! -e $ts_trailerdir ]
- then
- echo "Trailer directory doesn't exist, creating it now"
- mkdir $ts_trailerdir
- fi
- ########################
- # #
- # Select Database File #
- # #
- ########################
- echo Finding curent Kodi database
- # All Kodi video databases come in the format "MyVideosXXX.db", where the XXX is any seemingly
- # random number that increases as Kodi is updated. To find the latest, this line performs:-
- # 1. List all files in databse directory
- # 2. Limit to "MyVideos" files
- # 3. Show only the trailing numbers from these files
- # 4. Sort in decreasing numerical value
- # 5. Store the highest number as DBNumber, to be the base for the variable DBFile
- DBNumber=$(ls $ts_databasedir | grep MyVideos | grep -o '[0-9]\{1,\}' | sort -gr | head -n 1)
- DBFile=MyVideos"$DBNumber".db
- echo Using database file $DBFile
- #####################
- # #
- # Extract MovieList #
- # #
- #####################
- echo Extracting MovieList from Kodi database
- sqlite3 $ts_databasedir$DBFile "select c00 from movie order by c00;" >> $ts_tempdir"MovieList"
- MovieCount=$(wc -l < $ts_tempdir"MovieList")
- echo $MovieCount movies found
- #############
- ### ###
- # # MAIN LOOP # #
- ### ###
- #############
- # Loop through the Movie list
- COUNTER=0
- while [ $COUNTER -lt $MovieCount ]; do
- # Cut a single film out of the list based on the Counter
- let COUNTER=$COUNTER+1
- head -n$COUNTER $ts_tempdir"MovieList" > $ts_tempdir"CurrentMovie"
- ScanFilm=$(tail -n1 $ts_tempdir"CurrentMovie")
-
-
- # Pass movie name to the download handler
- trailer_dl "$ScanFilm"
- done
- echo All Movies checked.
- ###################
- # #
- # Report failures #
- # #
- ###################
- # Print list of failed films, so user can find get them manually
- if [ $FailedDL -gt 0 ]
- then
- echo Failed to find trailers for the following $FailedDL movies...
- echo -------------
- cat $ts_tempdir"FailedFilms"
- echo -------------
- # Save a copy of all failed films in a log file
- CurrDate=$(date)
- echo "QYTTS failure log for "$CurrDate > $StartDir"/FailedTrailers.log"
- cat $ts_tempdir"FailedFilms" >> $StartDir"/FailedTrailers.log"
- echo Log of failures saved as "FailedTrailers.log"
- else
- echo All missing trailers downloaded successfully
- fi
- ############
- # #
- # CLEANING #
- # #
- ############
- echo Cleaning up...
- # Remove temp files
- rm $ts_tempdir"CurrentMovie"
- rm $ts_tempdir"MovieList"
- rm $ts_tempdir"YTSearchList"
- rm $ts_tempdir"TopResult"
- rm $ts_tempdir"FailedFilms"
- rm $ts_tempdir"YTDLErrors"
-
-
- # Check for mp4 files in temp directory and remove if found
- # (sometimes left behind from youtube-dl issues)
- if [ $(ls $ts_tempdir | grep .mp4 | wc -l) -gt 0 ]
- then
- rm $ts_tempdir*.mp4
- fi
-
- # Return to initial directory
- cd $StartDir
- ########
- # Exit #
- ########
- echo Thanks for using QYTTS
- exit
|