Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1376566d48 | ||
|
|
f7d96c204f | ||
|
|
f2f4413e28 | ||
|
|
635aa556dd | ||
|
|
067c7785c0 | ||
|
|
a986bb450d | ||
|
|
61a944f322 | ||
|
|
4e0a5c4321 | ||
|
|
58cba08405 | ||
|
|
1d5c60bd3f | ||
|
|
32ebce8d89 | ||
|
|
40bfb99eff | ||
|
|
6dedbf2f72 | ||
|
|
e70bf17a70 | ||
|
|
1478264a00 | ||
|
|
ffcfb2220d | ||
|
|
7a5cfb5306 | ||
|
|
b0be50c291 | ||
|
|
7264409de4 | ||
|
|
56ab1c8c99 | ||
|
|
5cffb7a527 | ||
|
|
575e0e36b4 | ||
|
|
032b461e84 | ||
|
|
8a4318885a | ||
|
|
698cae773a | ||
|
|
1c4ddb9a87 | ||
|
|
4105c5bb85 | ||
|
|
2bd9ef3375 | ||
|
|
88d9e83c1c | ||
|
|
9898c33818 | ||
|
|
d52d872665 | ||
|
|
5e8b35fc17 | ||
|
|
4c57df2672 | ||
|
|
2a4a2ff7e1 | ||
|
|
8572a0b21f | ||
|
|
30ee175cff | ||
|
|
02e7154e34 | ||
|
|
6ae9949341 | ||
|
|
e042192cfb | ||
|
|
b39a6baf2d | ||
|
|
eb9555f3d2 | ||
|
|
c2d6db048c | ||
|
|
51b55f6bc7 | ||
|
|
8b1c0966f7 |
10
.abcde.conf
10
.abcde.conf
@@ -63,26 +63,26 @@ CDPARANOIAOPTS="--never-skip=40"
|
||||
CDDISCID=cd-discid
|
||||
|
||||
# Give the base location here for the encoded music files.
|
||||
OUTPUTDIR="/mnt/media/ARM/"
|
||||
OUTPUTDIR="/mnt/media/ARM/Media/Music/"
|
||||
|
||||
# The default actions that abcde will take.
|
||||
ACTIONS=cddb,playlist,getalbumart,read,encode,tag,move,clean
|
||||
ACTIONS=cddb,playlist,getalbumart,read,encode,replaygain,tag,move,clean
|
||||
|
||||
# Decide here how you want the tracks labelled for a standard 'single-artist',
|
||||
# multi-track encode and also for a multi-track, 'various-artist' encode:
|
||||
OUTPUTFORMAT='${OUTPUT}/${ARTISTFILE}/${ALBUMFILE}/${TRACKNUM}.${TRACKFILE}'
|
||||
VAOUTPUTFORMAT='${OUTPUT}/Various-${ALBUMFILE}/${TRACKNUM}.${ARTISTFILE}-${TRACKFILE}'
|
||||
VAOUTPUTFORMAT='${OUTPUT}/Various Artists/${ALBUMFILE}/${TRACKNUM}.${ARTISTFILE}-${TRACKFILE}'
|
||||
|
||||
# Decide here how you want the tracks labelled for a standard 'single-artist',
|
||||
# single-track encode and also for a single-track 'various-artist' encode.
|
||||
# (Create a single-track encode with 'abcde -1' from the commandline.)
|
||||
ONETRACKOUTPUTFORMAT='${OUTPUT}/${ARTISTFILE}/${ALBUMFILE}/${ALBUMFILE}'
|
||||
VAONETRACKOUTPUTFORMAT='${OUTPUT}/Various-${ALBUMFILE}/${ALBUMFILE}'
|
||||
VAONETRACKOUTPUTFORMAT='${OUTPUT}/Various Artists/${ALBUMFILE}/${ALBUMFILE}'
|
||||
|
||||
# Create playlists for single and various-artist encodes. I would suggest
|
||||
# commenting these out for single-track encoding.
|
||||
PLAYLISTFORMAT='${OUTPUT}/${ARTISTFILE}/${ALBUMFILE}/${ALBUMFILE}.m3u'
|
||||
VAPLAYLISTFORMAT='${OUTPUT}/Various-${ALBUMFILE}/${ALBUMFILE}.m3u'
|
||||
VAPLAYLISTFORMAT='${OUTPUT}/Various Artists/${ALBUMFILE}/${ALBUMFILE}.m3u'
|
||||
|
||||
# This function takes out dots preceding the album name, and removes a grab
|
||||
# bag of illegal characters. It allows spaces, if you do not wish spaces add
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,4 +2,5 @@ logs/*
|
||||
test.sh
|
||||
archive/
|
||||
config
|
||||
|
||||
temp/
|
||||
test.py
|
||||
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "build"]
|
||||
path = build
|
||||
url = https://github.com/caarlos0/shell-travis-build.git
|
||||
12
.travis.yml
Normal file
12
.travis.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
language: bash
|
||||
sudo: required
|
||||
os:
|
||||
- linux
|
||||
before_script:
|
||||
- cp ./config.sample config
|
||||
install:
|
||||
- ./build/install.sh
|
||||
script:
|
||||
- ./build/build.sh
|
||||
notifications:
|
||||
email: false
|
||||
35
CHANGELOG.md
Normal file
35
CHANGELOG.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Changelog
|
||||
|
||||
## v1.3.0
|
||||
- Get Title for DVD and Blu-Rays so that media servesr can identify them easily.
|
||||
- Determine if video is Movie or TV-Show from OMDB API query so that different actions can be taken (TV shows usually require manual episode identification)
|
||||
- Option for MakeMKV to rip using backup method.
|
||||
- Option to rip only main feature if so desired.
|
||||
|
||||
## v1.2.0
|
||||
- Distinguish UDF data from UDF video discs
|
||||
|
||||
## v1.1.1
|
||||
|
||||
- Added devname to abcde command
|
||||
- Added logging stats (timers). "grep STAT" to see parse them out.
|
||||
|
||||
## v1.1.0
|
||||
|
||||
- Added ability to rip from multiple drives at the same time
|
||||
- Added a config file for parameters
|
||||
- Changed logging
|
||||
- Log name is based on ID_FS_LABEL (dvd name) variable set by udev in order to isolate logging from multiple process running simultaneously
|
||||
- Log file name and path set in config file
|
||||
- Log file cleanup based on parameter set in config file
|
||||
- Added phone notification options for Pushbullet and IFTTT
|
||||
- Remove MakeMKV destination directory after HandBrake finishes transcoding
|
||||
- Misc stuff
|
||||
|
||||
## v1.0.1
|
||||
|
||||
- Fix ripping "Audio CDs" in ISO9660 format like LOTR.
|
||||
|
||||
## v1.0.0
|
||||
|
||||
- Initial Release
|
||||
5
README
5
README
@@ -1,5 +0,0 @@
|
||||
Automatic Ripping Machine (ARM)
|
||||
|
||||
See: https://b3n.org/automatic-ripping-machine
|
||||
|
||||
|
||||
87
README.md
Normal file
87
README.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# Automatic Ripping Machine (ARM)
|
||||
|
||||
[](https://travis-ci.org/ahnooie/automatic-ripping-machine)
|
||||
|
||||
## Overview
|
||||
|
||||
Insert an optical disc (Blu-Ray, DVD, CD) and checks to see if it's audio, video (Movie or TV), or data, then rips it.
|
||||
|
||||
See: https://b3n.org/automatic-ripping-machine
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- Detects insertion of disc using udev
|
||||
- Determines disc type...
|
||||
- If video (Blu-Ray or DVD)
|
||||
- Retrieve title from disc or Windows Media MetaServices API to name the folder "movie title (year)" so that Plex or Emby can pick it up
|
||||
- Determine if video is Movie or TV using OMDb API
|
||||
- Rip using MakeMKV (can rip all features or main feature)
|
||||
- Eject disc and queue up Handbrake transcoding when done
|
||||
- Transcoding jobs are asynchronusly batched from ripping
|
||||
- Send notification when done via IFTTT or Pushbullet
|
||||
- If audio (CD) - rip using abcde
|
||||
- If data (Blu-Ray, DVD, or CD) - make an ISO backup
|
||||
- Headless, designed to be run from a server
|
||||
- Can rip from multiple-optical drives in parallel
|
||||
|
||||
|
||||
## Requirements
|
||||
|
||||
- Ubuntu Server 16.04 (should work with other Linux distros)
|
||||
- One or more optical drives to rip Blu-Rays, DVDs, and CDs
|
||||
- Lots of drive space (I suggest using a NAS like FreeNAS) to store your movies
|
||||
|
||||
## Install
|
||||
|
||||
If you have a new DVD drive that you haven't used before, some require setting the region before they can play anything. Be aware most DVD players only let you change the region a handful (4 or 5?) of times then lockout any further changes. If your region is already set or you have a region free DVD drive you can skip this step.
|
||||
|
||||
sudo apt-get install regionset
|
||||
sudo regionset /dev/sr0
|
||||
|
||||
sudo apt-get install git
|
||||
sudo add-apt-repository ppa:heyarje/makemkv-beta
|
||||
sudo add-apt-repository ppa:stebbins/handbrake-releases
|
||||
sudo add-apt-repository ppa:mc3man/xerus-media
|
||||
sudo apt update
|
||||
sudo apt install makemkv-bin makemkv-oss
|
||||
sudo apt install handbrake-cli libavcodec-extra
|
||||
sudo apt install abcde flac imagemagick glyrc cdparanoia
|
||||
sudo apt install at
|
||||
sudo apt install python3 python3-pip
|
||||
sudo apt-get install libdvd-pkg
|
||||
sudo dpkg-reconfigure libdvd-pkg
|
||||
sudo su
|
||||
cd /opt
|
||||
git clone https://github.com/ahnooie/automatic-ripping-machine.git arm
|
||||
cd arm
|
||||
pip3 install -r requirements.txt
|
||||
ln -s /opt/arm/51-automedia.rules /lib/udev/rules.d/
|
||||
ln -s /opt/arm/.abcde.conf /root/
|
||||
cp config.sample config
|
||||
|
||||
- Edit your "config" file to determine what options you'd like to use
|
||||
- To rip Blu-Rays after the MakeMKV trial is up you will need to purchase a license key or while MakeMKV is in BETA you can get a free key (which you will need to update from time to time) here: https://www.makemkv.com/forum2/viewtopic.php?f=5&t=1053 and create /root/.MakeMKV/settings.conf with the contents:
|
||||
|
||||
app_Key = "insertlicensekeyhere"
|
||||
|
||||
|
||||
Optionally if you want something more stable than master you can download the latest release from the releases page.
|
||||
|
||||
## Usage
|
||||
|
||||
- Insert disc
|
||||
- Wait for disc to eject
|
||||
- Repeat
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Check /opt/arm/log to see if you can find where the script failed. If you need any help feel free to open an issue.
|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests are welcome
|
||||
|
||||
## License
|
||||
|
||||
[MIT License](LICENSE)
|
||||
@@ -1,2 +1,2 @@
|
||||
#!/bin/bash
|
||||
echo bash /opt/arm/identify.sh | at now
|
||||
echo bash /opt/arm/identify.sh /opt/arm/config | at now
|
||||
|
||||
1
build
Submodule
1
build
Submodule
Submodule build added at 5f3e72c711
154
config.sample
Normal file → Executable file
154
config.sample
Normal file → Executable file
@@ -1,71 +1,173 @@
|
||||
#!/bin/bash
|
||||
# ARM (Automatic Ripping Machine) oonfig file
|
||||
|
||||
#################
|
||||
## ARM Options ##
|
||||
#################
|
||||
|
||||
# Distinguish UDF video discs from UDF data discs. Requires mounting disc so adds a few seconds to the identify script.
|
||||
ARM_CHECK_UDF=true
|
||||
|
||||
# When enabled if the disc is a DVD use dvdid to calculate a crc64 and query Windows Media Meta Services for the Movie Title.
|
||||
# For BluRays attempts to extract the title from an XML file on the disc
|
||||
GET_VIDEO_TITLE=true
|
||||
|
||||
# Skip transcoding if you want the original MakeMKV files as your final output
|
||||
# Thiw will produce the highest quality videos (and use the most storage)
|
||||
# Note: RIPMETHOD must be set to "mkv" for this feature to work
|
||||
SKIP_TRANSCODE=false
|
||||
|
||||
#####################
|
||||
## Directory setup ##
|
||||
#####################
|
||||
|
||||
#Base directory of ARM media directory
|
||||
#Ripped and transcoded files end up here
|
||||
ARMPATH="/mnt/media/ARM/"
|
||||
# Base directory of ARM media directory
|
||||
# Ripped and transcoded files end up here
|
||||
ARMPATH="/mnt/media/ARM/Media/Unidentified/"
|
||||
|
||||
#Path to raw MakeMKV directory
|
||||
#Destination for MakeMKV and source for HandBrake
|
||||
# Path to raw MakeMKV directory
|
||||
# Destination for MakeMKV and source for HandBrake
|
||||
RAWPATH="/mnt/media/ARM/raw/"
|
||||
|
||||
#Path to directory to hold log files
|
||||
#Make sure to include trailing /
|
||||
# Path to final media directory
|
||||
# Destination for final file. Only used for movies that are positively identified
|
||||
MEDIA_DIR="/mnt/media/ARM/Media/Movies/"
|
||||
|
||||
# Path to directory to hold log files
|
||||
# Make sure to include trailing /
|
||||
LOGPATH="/opt/arm/logs/"
|
||||
|
||||
#How long to let log files live before deleting (in days)
|
||||
# How long to let log files live before deleting (in days)
|
||||
LOGLIFE=1
|
||||
|
||||
########################
|
||||
## File Permissions ##
|
||||
########################
|
||||
|
||||
# Enabling this seting will allow you to adjust the default file permissions of the outputted files
|
||||
# The default value is set to 777 for read/write/execute for all users, but can be changed below using the "CHMOD_VALUE" setting
|
||||
# This setting is helpfuly when storing the data locally on the system
|
||||
SET_MEDIA_PERMISSIONS=false
|
||||
CHMOD_VALUE=777
|
||||
|
||||
########################
|
||||
## MakeMKV Parameters ##
|
||||
########################
|
||||
|
||||
#Minimum length of track for MakeMKV rip (in seconds)
|
||||
# Minimum length of track for MakeMKV rip (in seconds)
|
||||
MINLENGTH="600"
|
||||
|
||||
# Method of MakeMKV to use for Blu Ray discs. Options are "mkv" or "backup".
|
||||
# mkv is the normal method of ripping mkv files directly from the DVD
|
||||
# backup decrypts the dvd and then copies it to the hard drive. This allows HandBrake to apply some of it's
|
||||
# analytical abilities such as the main-feature identification. This method seems to offer success on bluray
|
||||
# discs that fail in "mkv" mode. *** NOTE: MakeMKV only supports the backup method on BluRay discs. Regular
|
||||
# DVD's will always default back to the "mkv" mode. If this is set to "backup" then you must also set HandBrake's MAINFEATURE to true.
|
||||
RIPMETHOD="mkv"
|
||||
|
||||
# MakeMKV Arguments
|
||||
# MakeMKV Profile used for controlling Audio Track Selection.
|
||||
# This is the default profile MakeMKV uses for Audio track selection. Updating this file or changing it is considered
|
||||
# to be advanced usage of MakeMKV. But this will allow users to alternatively tell makemkv to select HD audio tracks and etc.
|
||||
# MKV_ARGS="--profile=/opt/arm/default.mmcp.xml"
|
||||
MKV_ARGS=""
|
||||
|
||||
##########################
|
||||
## HandBrake Parameters ##
|
||||
##########################
|
||||
|
||||
# Handbrake preset profile
|
||||
# See https://trac.handbrake.fr/wiki/BuiltInPresets
|
||||
# Execute "HandBrakeCLI -z" to see a list of all presets
|
||||
HB_PRESET="High Profile"
|
||||
|
||||
#Extension of the final video file
|
||||
# Extension of the final video file
|
||||
DEST_EXT=mkv
|
||||
|
||||
#Handbrake binary to call
|
||||
# Handbrake binary to call
|
||||
HANDBRAKE_CLI=HandBrakeCLI
|
||||
|
||||
# Have HandBrake transcode the main feature only. BluRay discs must have RIPMETHOD="backup" for this to work.
|
||||
# If MAINFEATURE is true, blurays will be backed up to the HD and then HandBrake will go to work on the backed up
|
||||
# files. For normal DVDs, ARM will bypass MakeMKV and hand off the dvd directly to HandBrake. This will require
|
||||
# libdvdcss2 be installed.
|
||||
# NOTE: For the most part, HandBrake correctly identifies the main feature on movie DVD's, although it is not perfect.
|
||||
# However, it does not handle tv shows well at all. You will likely want this value to be false when ripping tv shows.
|
||||
MAINFEATURE=false
|
||||
|
||||
# Additional HandBrake arguments.
|
||||
HB_ARGS="--subtitle scan -F"
|
||||
|
||||
#####################
|
||||
## Enable Plex Use ##
|
||||
#####################
|
||||
|
||||
# Set this setting to true, to enable Plex Extras support
|
||||
PLEX_SUPPORT=false
|
||||
|
||||
#####################
|
||||
## Emby Parameters ##
|
||||
#####################
|
||||
|
||||
# Parameters to enable automatic library scan in Emby. This will trigger only if MainFeature is true above.
|
||||
|
||||
# Scan emby library after succesful placement of mainfeature (see above)
|
||||
EMBY_REFRESH=false
|
||||
|
||||
# Use subfolders in Emby as described here: https://github.com/MediaBrowser/Wiki/wiki/Movie%20naming#movie-extras
|
||||
EMBY_SUBFOLDERS=true
|
||||
|
||||
# Server parameters
|
||||
# Server can be ip address or domain name
|
||||
EMBY_SERVER=""
|
||||
EMBY_PORT="8096"
|
||||
|
||||
# Emby authentication fluff parameters. These can be anything.
|
||||
EMBY_CLIENT="ARM"
|
||||
EMBY_DEVICE="ARM"
|
||||
EMBY_DEVICEID="ARM"
|
||||
|
||||
# Emby authentication parameters. These are parameters that must be set to a current user in Emby.
|
||||
EMBY_USERNAME=""
|
||||
|
||||
# EMBY_USERID is the user ID associated with the username above. You can find this by going to the following address on your emby server
|
||||
# <server>:<port>/Users/Public and getting the ID value for the username above.
|
||||
EMBY_USERID=""
|
||||
|
||||
# This is the SHA1 encrypted password for the username above. You can generate the SHA1 hash of your password by executing the following at
|
||||
# the command line:
|
||||
# echo -n your-password | sha1sum | awk '{print $1}'
|
||||
# or using an online generator like the one located at http://www.sha1-online.com/
|
||||
EMBY_PASSWORD=""
|
||||
|
||||
#############################
|
||||
## Notification Parameters ##
|
||||
#############################
|
||||
|
||||
#Pushbullet API Key
|
||||
#Leave empty or comment out to disable Pushbullet notifications
|
||||
#PB_KEY=""
|
||||
# Pushbullet API Key
|
||||
# Leave empty or comment out to disable Pushbullet notifications
|
||||
PB_KEY=""
|
||||
|
||||
#IFTTT API KEY
|
||||
#Leave empty or comment out to disable IFTTT notifications
|
||||
#IFTTT_KEY=""
|
||||
# IFTTT API KEY
|
||||
# Leave empty or comment out to disable IFTTT notifications
|
||||
# IFTTT_KEY=""
|
||||
|
||||
#IFTTT Event Name
|
||||
# IFTTT Event Name
|
||||
IFTTT_EVENT="arm_event"
|
||||
|
||||
#Determine logfile name
|
||||
#use the label of the DVD/CD or else use empty.log
|
||||
#this is required for udev events where there is no media available
|
||||
#such as ejecting the drive
|
||||
if [ -z $ID_FS_LABEL]; then
|
||||
# Pushover API User and Application Key
|
||||
# Leave User key empty or comment out to disable Pushover notifications
|
||||
PO_USER_KEY=""
|
||||
PO_APP_KEY=""
|
||||
|
||||
# Determine logfile name
|
||||
# use the label of the DVD/CD or else use empty.log
|
||||
# this is required for udev events where there is no media available
|
||||
# such as ejecting the drive
|
||||
if [ -z "$ID_FS_LABEL" ]; then
|
||||
LOGFILE="empty.log"
|
||||
else
|
||||
LOGFILE=${ID_FS_LABEL}".log"
|
||||
fi
|
||||
|
||||
#Set full logfile path
|
||||
# Set full logfile path
|
||||
LOG=$LOGPATH$LOGFILE
|
||||
|
||||
|
||||
27
data_rip.sh
27
data_rip.sh
@@ -1,22 +1,27 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Rip Data using DD
|
||||
source /opt/arm/config
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
# shellcheck source=config
|
||||
source "$ARM_CONFIG"
|
||||
|
||||
{
|
||||
|
||||
|
||||
|
||||
TIMESTAMP=`date '+%Y%m%d_%H%M%S'`;
|
||||
DEST=/mnt/media/ARM/${TIMESTAMP}_${ID_FS_LABEL}
|
||||
mkdir $DEST
|
||||
TIMESTAMP=$(date '+%Y%m%d_%H%M%S');
|
||||
DEST="/mnt/media/ARM/Media/Data/${TIMESTAMP}_${ID_FS_LABEL}"
|
||||
mkdir -p "$DEST"
|
||||
FILENAME=${ID_FS_LABEL}_disc.iso
|
||||
|
||||
|
||||
#dd if=/dev/sr0 of=$DEST/$FILENAME
|
||||
cat /dev/sr0 > $DEST/$FILENAME
|
||||
cat "$DEVNAME" > "$DEST/$FILENAME"
|
||||
|
||||
eject
|
||||
eject "$DEVNAME"
|
||||
|
||||
if [ "$SET_MEDIA_PERMISSIONS" = true ]; then
|
||||
|
||||
chmod -R "$CHMOD_VALUE" "$DEST"
|
||||
|
||||
fi
|
||||
|
||||
|
||||
} >> $LOG
|
||||
} >> "$LOG"
|
||||
|
||||
69
default.mmcp.xml
Normal file
69
default.mmcp.xml
Normal file
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<profile>
|
||||
<!-- profile name - Default -->
|
||||
<name lang="mogz">:5086</name>
|
||||
|
||||
<!-- Common MKV flags -->
|
||||
<mkvSettings
|
||||
ignoreForcedSubtitlesFlag="true"
|
||||
useISO639Type2T="false"
|
||||
setFirstAudioTrackAsDefault="true"
|
||||
setFirstSubtitleTrackAsDefault="true"
|
||||
setFirstForcedSubtitleTrackAsDefault="true"
|
||||
insertFirstChapter00IfMissing="true"
|
||||
/>
|
||||
|
||||
<!-- Settings overridable in preferences -->
|
||||
<profileSettings
|
||||
app_DefaultSelectionString="-sel:all,+sel:(favlang|nolang|single),-sel:(havemulti|havecore),-sel:mvcvideo,=100:all,-10:favlang"
|
||||
/>
|
||||
|
||||
<!-- Output formats currently supported by MakeMKV -->
|
||||
<outputSettings name="copy" outputFormat="directCopy">
|
||||
<description lang="eng">Copy track as is</description>
|
||||
<description lang="ger">Track 1:1 kopieren</description>
|
||||
</outputSettings>
|
||||
|
||||
<outputSettings name="lpcm" outputFormat="LPCM-raw">
|
||||
<description lang="eng">Save as raw LPCM</description>
|
||||
<description lang="ger">Als RAW LPCM speichern</description>
|
||||
</outputSettings>
|
||||
|
||||
<outputSettings name="wavex" outputFormat="LPCM-wavex">
|
||||
<description lang="eng">Save as LPCM in WAV container</description>
|
||||
<description lang="ger">Als LPCM im WAV-Container speichern</description>
|
||||
</outputSettings>
|
||||
|
||||
<outputSettings name="flac-best" outputFormat="FLAC">
|
||||
<description lang="eng">Save as FLAC (best compression)</description>
|
||||
<description lang="ger">Als FLAC speichern (höchste Komprimierungsstufe)</description>
|
||||
<extraArgs>-compression_level 12</extraArgs>
|
||||
</outputSettings>
|
||||
|
||||
<outputSettings name="flac-fast" outputFormat="FLAC">
|
||||
<description lang="eng">Save as FLAC (fast compression)</description>
|
||||
<extraArgs>-compression_level 5</extraArgs>
|
||||
</outputSettings>
|
||||
|
||||
<!-- Default rule - copy as is -->
|
||||
<trackSettings input="default">
|
||||
<output outputSettingsName="copy"
|
||||
defaultSelection="$app_DefaultSelectionString">
|
||||
</output>
|
||||
</trackSettings>
|
||||
|
||||
<!-- Save LPCM mono or stereo as raw LPCM -->
|
||||
<trackSettings input="LPCM-stereo">
|
||||
<output outputSettingsName="lpcm"
|
||||
defaultSelection="$app_DefaultSelectionString">
|
||||
</output>
|
||||
</trackSettings>
|
||||
|
||||
<!-- Put multi-channel LPCM into WAVEX container-->
|
||||
<trackSettings input="LPCM-multi">
|
||||
<output outputSettingsName="wavex"
|
||||
defaultSelection="$app_DefaultSelectionString">
|
||||
</output>
|
||||
</trackSettings>
|
||||
|
||||
</profile>
|
||||
74
getmovietitle.py
Executable file
74
getmovietitle.py
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import argparse
|
||||
import urllib
|
||||
import os
|
||||
import datetime
|
||||
import pydvdid
|
||||
import unicodedata
|
||||
import xmltodict
|
||||
import sys
|
||||
import re
|
||||
|
||||
|
||||
def entry():
|
||||
""" Entry to program, parses arguments"""
|
||||
parser = argparse.ArgumentParser(description='Get Movie Title from DVD or Blu-Ray')
|
||||
parser.add_argument('-p', '--path', help='Mount path to disc', required=True)
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
def getdvdtitle():
|
||||
""" Calculates CRC64 for the DVD and calls Windows Media
|
||||
Metaservices and returns the Title and year of DVD """
|
||||
crc64 = pydvdid.compute(args.path)
|
||||
# print (crc64)
|
||||
dvd_info_xml = urllib.request.urlopen(
|
||||
"http://metaservices.windowsmedia.com/pas_dvd_B/template/GetMDRDVDByCRC.xml?CRC={0}".
|
||||
format(crc64)).read()
|
||||
|
||||
doc = xmltodict.parse(dvd_info_xml)
|
||||
dvd_title = doc['METADATA']['MDR-DVD']['dvdTitle']
|
||||
dvd_release_date = doc['METADATA']['MDR-DVD']['releaseDate']
|
||||
|
||||
# title + release year
|
||||
return dvd_title + " (" + dvd_release_date.split()[0] + ")"
|
||||
|
||||
def getbluraytitle():
|
||||
""" Get's Blu-Ray title by parsing XML in bdmt_eng.xml """
|
||||
with open(args.path + '/BDMV/META/DL/bdmt_eng.xml', "rb") as xml_file:
|
||||
doc = xmltodict.parse(xml_file.read())
|
||||
|
||||
|
||||
bluray_title = doc['disclib']['di:discinfo']['di:title']['di:name']
|
||||
|
||||
bluray_modified_timestamp = os.path.getmtime(args.path + '/BDMV/META/DL/bdmt_eng.xml')
|
||||
bluray_year = (datetime.datetime.fromtimestamp(bluray_modified_timestamp).strftime('%Y'))
|
||||
|
||||
bluray_title = unicodedata.normalize('NFKD', bluray_title).encode('ascii', 'ignore').decode()
|
||||
|
||||
bluray_title = bluray_title.replace(' - Blu-rayTM', '')
|
||||
bluray_title = bluray_title.replace(' - BLU-RAYTM', '')
|
||||
bluray_title = bluray_title.replace(' - BLU-RAY', '')
|
||||
bluray_title = bluray_title.replace(' - Blu-ray', '')
|
||||
return bluray_title + " (" + bluray_year + ")"
|
||||
|
||||
def clean_for_filename(string):
|
||||
""" Cleans up string for use in filename """
|
||||
string = re.sub('\[(.*?)\]', '', string)
|
||||
string = re.sub( '\s+', ' ', string)
|
||||
string = string.replace(' : ',' - ')
|
||||
string = string.replace(': ',' - ')
|
||||
return re.sub('[^\w\-_\.\(\) ]', '', string)
|
||||
|
||||
#pylint: disable=C0103
|
||||
|
||||
args = entry()
|
||||
|
||||
try:
|
||||
disc_title = clean_for_filename(getdvdtitle())
|
||||
except:
|
||||
disc_title = clean_for_filename(getbluraytitle())
|
||||
print(disc_title)
|
||||
else:
|
||||
print(disc_title)
|
||||
101
getvideotype.py
Executable file
101
getvideotype.py
Executable file
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import argparse
|
||||
import urllib
|
||||
import os
|
||||
import xmltodict
|
||||
import json
|
||||
import re
|
||||
|
||||
def entry():
|
||||
""" Entry to program, parses arguments"""
|
||||
parser = argparse.ArgumentParser(description='Get type of dvd--movie or tv series')
|
||||
parser.add_argument('-t', '--title', help='Title', required=True)
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
def getdvdtype():
|
||||
""" Queries OMDbapi.org for title information and parses if it's a movie
|
||||
or a tv series """
|
||||
dvd_title = args.title
|
||||
needs_new_year = "false"
|
||||
|
||||
try:
|
||||
year = dvd_title[(dvd_title.rindex('(')):len(dvd_title)]
|
||||
except:
|
||||
year = ""
|
||||
else:
|
||||
year = re.sub('[()]','', year)
|
||||
|
||||
try:
|
||||
dvd_title = dvd_title[0:(dvd_title.rindex('('))].strip()
|
||||
except:
|
||||
dvd_title_clean = cleanupstring(dvd_title)
|
||||
else:
|
||||
dvd_title_clean = cleanupstring(dvd_title)
|
||||
|
||||
if year is None:
|
||||
year = ""
|
||||
|
||||
dvd_type = callwebservice(dvd_title_clean, year)
|
||||
# print (dvd_type)
|
||||
|
||||
# handle failures
|
||||
# this is kind of kludgy, but it kind of work...
|
||||
if (dvd_type == "fail"):
|
||||
|
||||
# first try submitting without the year
|
||||
dvd_type = callwebservice(dvd_title_clean, "")
|
||||
# print (dvd_type)
|
||||
|
||||
if (dvd_type != "fail"):
|
||||
#that means the year is wrong.
|
||||
needs_new_year = "true"
|
||||
|
||||
if (dvd_type == "fail"):
|
||||
# second see if there is a hyphen and split it
|
||||
if (dvd_title.find("-") > -1):
|
||||
dvd_title_slice = dvd_title[:dvd_title.find("-")]
|
||||
dvd_title_slice =cleanupstring(dvd_title_slice)
|
||||
dvd_type = callwebservice(dvd_title_slice)
|
||||
|
||||
# if still fail, then try slicing off the last word in a loop
|
||||
while dvd_type == "fail" and dvd_title_clean.count('+') > 0:
|
||||
dvd_title_clean = dvd_title_clean.rsplit('+', 1)[0]
|
||||
dvd_type = callwebservice(dvd_title_clean)
|
||||
|
||||
if needs_new_year == "true":
|
||||
#pass the new year back to bash to handle
|
||||
global new_year
|
||||
return dvd_type + "#" + new_year
|
||||
else:
|
||||
return dvd_type
|
||||
|
||||
def cleanupstring(string):
|
||||
# clean up title string to pass to OMDbapi.org
|
||||
string = string.strip()
|
||||
return re.sub('[_ ]',"+",string)
|
||||
|
||||
def callwebservice(dvd_title, year=""):
|
||||
""" Queries OMDbapi.org for title information and parses if it's a movie
|
||||
or a tv series """
|
||||
# print (dvd_title)
|
||||
|
||||
try:
|
||||
dvd_title_info_json = urllib.request.urlopen("http://www.omdbapi.com/?t={0}&y={1}&plot=short&r=json".format(dvd_title, year)).read()
|
||||
except:
|
||||
return "fail"
|
||||
else:
|
||||
doc = json.loads(dvd_title_info_json.decode())
|
||||
if doc['Response'] == "False":
|
||||
return "fail"
|
||||
else:
|
||||
global new_year
|
||||
new_year = doc['Year']
|
||||
return doc['Type']
|
||||
|
||||
args = entry()
|
||||
|
||||
dvd_type = getdvdtype()
|
||||
print(dvd_type)
|
||||
130
identify.sh
130
identify.sh
@@ -1,43 +1,125 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
source /opt/arm/config
|
||||
|
||||
export ARM_CONFIG=$1
|
||||
|
||||
echo "$ARM_CONFIG"
|
||||
|
||||
# shellcheck source=config
|
||||
# shellcheck disable=SC1091
|
||||
source "$ARM_CONFIG"
|
||||
|
||||
# Create log dir if needed
|
||||
mkdir -p $LOGPATH
|
||||
mkdir -p "$LOGPATH"
|
||||
|
||||
#shellcheck disable=SC2094
|
||||
{
|
||||
echo "Starting Identify Script..." >> $LOG
|
||||
# echo all config parameters to logfile
|
||||
# excludes sensative parameters
|
||||
# shellcheck disable=SC2129
|
||||
echo "*** Start config parameters ****" >> "$LOG"
|
||||
# shellcheck disable=SC2002
|
||||
cat "$ARM_CONFIG"|sed '/^[#;].*$/d;/^$/d;/if/d;/^ /d;/^else/d;/^fi/d;/KEY=/d;/PASSWORD/d' >> "$LOG"
|
||||
echo "*** End config parameters ****" >> "$LOG"
|
||||
|
||||
echo "Starting Identify Script..." >> "$LOG"
|
||||
|
||||
VIDEO_TITLE=""
|
||||
HAS_NICE_TITLE=""
|
||||
|
||||
|
||||
#Clean up old log files
|
||||
FILESFOUND=( $(find $LOGPATH -mtime +$LOGLIFE -type f))
|
||||
echo "Deleting ${#FILESFOUND[@]} old log files:"${FILESFOUND[@]} >> $LOG
|
||||
find $LOGPATH -mtime +$LOGLIFE -type f -delete
|
||||
FILESFOUND=( $(find "$LOGPATH" -mtime +"$LOGLIFE" -type f))
|
||||
echo "Deleting ${#FILESFOUND[@]} old log files: ${FILESFOUND[*]}" >> "$LOG"
|
||||
find "$LOGPATH" -mtime +"$LOGLIFE" -type f -delete
|
||||
|
||||
# Set Home to home folder of user that is setup to run MakeMKV
|
||||
export HOME="/root/"
|
||||
|
||||
# Output UDEV info
|
||||
udevadm info -q env -n "$DEVNAME" >> "$LOG"
|
||||
|
||||
if [ $ID_FS_TYPE == "udf" ]; then
|
||||
echo "identified video" >> $LOG
|
||||
echo "found ${ID_FS_LABEL} on ${DEVNAME}" >> $LOG
|
||||
#echo "ripping video" >> $LOG
|
||||
/opt/arm/video_rip.sh $LOG
|
||||
if [ "$ID_FS_TYPE" == "udf" ]; then
|
||||
echo "identified udf" >> "$LOG"
|
||||
echo "found ${ID_FS_LABEL} on ${DEVNAME}" >> "$LOG"
|
||||
|
||||
elif (($ID_CDROM_MEDIA_TRACK_COUNT_AUDIO > 0 )); then
|
||||
echo "identified audio" >> $LOG
|
||||
abcde
|
||||
if [ "$ARM_CHECK_UDF" == true ]; then
|
||||
# check to see if this is really a video
|
||||
mkdir -p /mnt/"$DEVNAME"
|
||||
mount "$DEVNAME" /mnt/"$DEVNAME"
|
||||
if [[ -d /mnt/${DEVNAME}/VIDEO_TS || -d /mnt/${DEVNAME}/BDMV ]]; then
|
||||
echo "identified udf as video" >> "$LOG"
|
||||
|
||||
elif [ $ID_FS_TYPE == "iso9660" ]; then
|
||||
echo "identified data" >> $LOG
|
||||
/opt/arm/data_rip.sh $LOG
|
||||
eject $DEVNAME
|
||||
if [ "$GET_VIDEO_TITLE" == true ]; then
|
||||
|
||||
GET_TITLE_OUTPUT=$(/opt/arm/getmovietitle.py -p /mnt"${DEVNAME}" 2>&1)
|
||||
GET_TITLE_RESULT=$?
|
||||
|
||||
if [ $GET_TITLE_RESULT = 0 ]; then
|
||||
echo "Obtained Title $GET_TITLE_OUTPUT"
|
||||
HAS_NICE_TITLE=true
|
||||
VIDEO_TITLE=${GET_TITLE_OUTPUT}
|
||||
else
|
||||
echo "failed to get title $GET_TITLE_OUTPUT"
|
||||
HAS_NICE_TITLE=false
|
||||
VIDEO_TITLE=${ID_FS_LABEL}
|
||||
fi
|
||||
|
||||
else
|
||||
HAS_NICE_TITLE=false
|
||||
VIDEO_TITLE=${ID_FS_LABEL}
|
||||
fi
|
||||
|
||||
if [ $HAS_NICE_TITLE == true ]; then
|
||||
VTYPE=$(/opt/arm/getvideotype.py -t "${VIDEO_TITLE}" 2>&1)
|
||||
|
||||
#handle year mismath if found
|
||||
if [[ $VTYPE =~ .*#.* ]]; then
|
||||
VIDEO_TYPE=$(echo "$VTYPE" | cut -f1 -d#)
|
||||
NEW_YEAR=$(echo "$VTYPE" | cut -f2 -d#)
|
||||
echo "VIDEO_TYPE is $VIDEO_TYPE and NEW_YEAR is $NEW_YEAR"
|
||||
VIDEO_TITLE="$(echo "$VIDEO_TITLE" | cut -f1 -d\()($NEW_YEAR)"
|
||||
echo "Year mismatch found. New video title is $VIDEO_TITLE"
|
||||
else
|
||||
VIDEO_TYPE="$VTYPE"
|
||||
fi
|
||||
else
|
||||
VIDEO_TYPE="unknown"
|
||||
fi
|
||||
|
||||
echo "got to here"
|
||||
echo "HAS_NICE_TITLE is ${HAS_NICE_TITLE}"
|
||||
echo "video title is now ${VIDEO_TITLE}"
|
||||
echo "video type is ${VIDEO_TYPE}"
|
||||
|
||||
umount "/mnt/$DEVNAME"
|
||||
/opt/arm/video_rip.sh "$VIDEO_TITLE" "$HAS_NICE_TITLE" "$VIDEO_TYPE" "$LOG"
|
||||
else
|
||||
umount "/mnt/$DEVNAME"
|
||||
echo "identified udf as data" >> "$LOG"
|
||||
/opt/arm/data_rip.sh
|
||||
eject "$DEVNAME"
|
||||
|
||||
fi
|
||||
else
|
||||
echo "ARM_CHECK_UDF is false, assuming udf is video" >> "$LOG"
|
||||
/opt/arm/video_rip.sh "$LOG"
|
||||
fi
|
||||
|
||||
|
||||
elif (("$ID_CDROM_MEDIA_TRACK_COUNT_AUDIO" > 0 )); then
|
||||
echo "identified audio" >> "$LOG"
|
||||
abcde -d "$DEVNAME"
|
||||
|
||||
elif [ "$ID_FS_TYPE" == "iso9660" ]; then
|
||||
echo "identified data" >> "$LOG"
|
||||
/opt/arm/data_rip.sh "$LOG"
|
||||
eject "$DEVNAME"
|
||||
else
|
||||
echo "unable to identify" >> $LOG
|
||||
echo $ID_CDROM_MEDIA_TRACK_COUNT_AUDIO >> $LOG
|
||||
echo $ID_FS_TYPE >> $LOG
|
||||
eject $DEVNAME
|
||||
echo "unable to identify"
|
||||
echo "$ID_CDROM_MEDIA_TRACK_COUNT_AUDIO" >> "$LOG"
|
||||
echo "$ID_FS_TYPE" >> "$LOG"
|
||||
eject "$DEVNAME"
|
||||
fi
|
||||
|
||||
|
||||
} >> $LOG
|
||||
} >> "$LOG"
|
||||
|
||||
30
notify.sh
30
notify.sh
@@ -1,26 +1,40 @@
|
||||
#!/bin/bash
|
||||
|
||||
source /opt/arm/config
|
||||
# shellcheck source=config
|
||||
# shellcheck disable=SC1091
|
||||
source "$ARM_CONFIG"
|
||||
MSG=$1
|
||||
|
||||
{
|
||||
#Notification via pushbullet
|
||||
#Trigger onl if variable is set
|
||||
if [ -z "$PB_KEY" ]; then
|
||||
echo "Pushbullet notifications not enabled" >> $LOG
|
||||
echo "Pushbullet notifications not enabled" >> "$LOG"
|
||||
else
|
||||
curl -s -u $PB_KEY: https://api.pushbullet.com/v2/pushes -d type=note -d title="Alert" -d body="$MSG"
|
||||
echo "Pushbullet notification sent" >> $LOG
|
||||
echo "Sending Pushbullet notification" >> "$LOG"
|
||||
curl -s -u "$PB_KEY": https://api.pushbullet.com/v2/pushes -d type=note -d title="Alert" -d body="$MSG"
|
||||
echo "Pushbullet notification sent" >> "$LOG"
|
||||
fi
|
||||
|
||||
#Notification via IFTTT
|
||||
#Trigger only if variable is set
|
||||
if [ -z "$IFTTT_KEY" ]; then
|
||||
echo "IFTTT notifications not enabled" >> $LOG
|
||||
echo "IFTTT notifications not enabled" >> "$LOG"
|
||||
else
|
||||
curl -s -X POST -H "Content-Type: application/json" -d '{"value1":"'"$MSG"'"}' https://maker.ifttt.com/trigger/${IFTTT_EVENT}/with/key/${IFTTT_KEY}
|
||||
printf "\nIFTTT notification sent" >> $LOG
|
||||
echo "Sending IFTTT notification" >> "$LOG"
|
||||
curl -s -X POST -H "Content-Type: application/json" -d '{"value1":"'"$MSG"'"}' https://maker.ifttt.com/trigger/"$IFTTT_EVENT"/with/key/"$IFTTT_KEY"
|
||||
printf "\nIFTTT notification sent" >> "$LOG"
|
||||
fi
|
||||
|
||||
} >> $LOG
|
||||
#Notification via Pushover
|
||||
#Trigger onl if variable is set
|
||||
if [ -z "$PO_USER_KEY" ]; then
|
||||
echo "Pusover notifications not enabled" >> "$LOG"
|
||||
else
|
||||
echo "Sending Pushover notification" >> "$LOG"
|
||||
curl -s --form-string "token=$PO_APP_KEY" --form-string "user=$PO_USER_KEY" --form-string "message=$MSG" https://api.pushover.net/1/messages.json
|
||||
echo "Pushover notification sent" >> "$LOG"
|
||||
fi
|
||||
|
||||
} >> "$LOG"
|
||||
|
||||
|
||||
5
requirements.txt
Normal file
5
requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
pycurl>=7.43.0
|
||||
pydvdid>=1.0
|
||||
requests>=2.9.1
|
||||
urllib3>=1.13.1
|
||||
xmltodict>=0.10.2
|
||||
64
video_rip.sh
64
video_rip.sh
@@ -1,24 +1,58 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Rip video using MakeMKV then eject and call transcode script
|
||||
|
||||
source /opt/arm/config
|
||||
# shellcheck source=config
|
||||
# shellcheck disable=SC1091
|
||||
source "$ARM_CONFIG"
|
||||
|
||||
VIDEO_TITLE=$1
|
||||
HAS_NICE_TITLE=$2
|
||||
VIDEO_TYPE=$3
|
||||
|
||||
{
|
||||
|
||||
echo "Ripping video ${ID_FS_LABEL} from ${DEVNAME}" >> $LOG
|
||||
TIMESTAMP=`date '+%Y%m%d_%H%M%S'`;
|
||||
DEST=${RAWPATH}/${ID_FS_LABEL}_${TIMESTAMP}
|
||||
mkdir $DEST
|
||||
echo "Video Title is ${VIDEO_TITLE}"
|
||||
echo "Ripping video ${ID_FS_LABEL} from ${DEVNAME}" >> "$LOG"
|
||||
TIMESTAMP=$(date '+%Y%m%d_%H%M%S');
|
||||
DEST="${RAWPATH}/${VIDEO_TITLE}_${TIMESTAMP}"
|
||||
RIPSTART=$(date +%s);
|
||||
|
||||
mkdir -p "$DEST"
|
||||
|
||||
#echo /opt/arm/video_transcode.sh \"$DEST\" \"$VIDEO_TITLE\" $TIMESTAMP >> $LOG
|
||||
if [ "$RIPMETHOD" = "backup" ] && [ "$ID_CDROM_MEDIA_BD" = "1" ]; then
|
||||
echo "Using backup method of ripping." >> "$LOG"
|
||||
DISC="${DEVNAME: -1}"
|
||||
# shellcheck disable=SC2086
|
||||
makemkvcon backup --decrypt $MKV_ARGS -r disc:"$DISC" "$DEST"/
|
||||
eject "$DEVNAME"
|
||||
elif [ "$MAINFEATURE" = true ] && [ "$ID_CDROM_MEDIA_DVD" = "1" ] && [ -z "$ID_CDROM_MEDIA_BD" ]; then
|
||||
echo "Media is DVD and Main Feature parameter in config file is true. Bypassing MakeMKV." >> "$LOG"
|
||||
# rmdir "$DEST"
|
||||
|
||||
echo "DEST is ${DEST}"
|
||||
else
|
||||
echo "Using mkv method of ripping." >> "$LOG"
|
||||
# shellcheck disable=SC2086
|
||||
makemkvcon mkv $MKV_ARGS dev:"$DEVNAME" all "$DEST" --minlength="$MINLENGTH" -r
|
||||
eject "$DEVNAME"
|
||||
fi
|
||||
|
||||
RIPEND=$(date +%s);
|
||||
RIPSEC=$((RIPEND-RIPSTART));
|
||||
RIPTIME="$((RIPSEC / 3600)) hours, $(((RIPSEC / 60) % 60)) minutes and $((RIPSEC % 60)) seconds."
|
||||
|
||||
#eject $DEVNAME
|
||||
|
||||
#echo /opt/arm/notify.sh "\"Ripped: ${ID_FS_LABEL} completed from ${DEVNAME} in ${RIPTIME}\"" |at now
|
||||
|
||||
echo "STAT: ${ID_FS_LABEL} ripped in ${RIPTIME}" >> "$LOG"
|
||||
|
||||
echo "/opt/arm/video_transcode.sh \"$DEST\" \"$VIDEO_TITLE\" \"$HAS_NICE_TITLE\" \"$VIDEO_TYPE\" $TIMESTAMP"
|
||||
echo "/opt/arm/video_transcode.sh \"$DEST\" \"$VIDEO_TITLE\" \"$HAS_NICE_TITLE\" \"$VIDEO_TYPE\" \"$TIMESTAMP\"" | batch
|
||||
|
||||
echo "${ID_FS_LABEL} sent to transcoding queue..." >> "$LOG"
|
||||
|
||||
|
||||
makemkvcon mkv dev:$DEVNAME all $DEST --minlength=$MINLENGTH -r
|
||||
|
||||
eject $DEVNAME
|
||||
|
||||
echo /opt/arm/notify.sh "\"Ripped: ${ID_FS_LABEL} completed from ${DEVNAME}\"" |at now
|
||||
|
||||
echo /opt/arm/video_transcode.sh $DEST $ID_FS_LABEL $TIMESTAMP | batch
|
||||
|
||||
|
||||
} >> $LOG
|
||||
} >> "$LOG"
|
||||
|
||||
@@ -1,39 +1,266 @@
|
||||
#!/bin/bash
|
||||
# Transcodes Video files using HandBrake and removes source files when done
|
||||
|
||||
source /opt/arm/config
|
||||
#SRC=/mnt/media/ARM/raw/
|
||||
# shellcheck source=config
|
||||
# shellcheck disable=SC1091
|
||||
source "$ARM_CONFIG"
|
||||
|
||||
SRC=$1
|
||||
LABEL=$2
|
||||
TIMESTAMP=$3
|
||||
#LOG=$4
|
||||
#DEST_EXT=mkv
|
||||
#HANDBRAKE_CLI=HandBrakeCLI
|
||||
#HB_PRESET="Normal"
|
||||
#HB_PRESET="High Profile"
|
||||
HAS_NICE_TITLE=$3
|
||||
VIDEO_TYPE=$4
|
||||
TIMESTAMP=$5
|
||||
|
||||
echo "Start video transcoding script" >> $LOG
|
||||
|
||||
DEST=${ARMPATH}/${LABEL}_${TIMESTAMP}
|
||||
mkdir $DEST
|
||||
TRANSSTART=$(date +%s);
|
||||
echo "Start video transcoding script" >> "$LOG"
|
||||
|
||||
for FILE in `ls $SRC`
|
||||
do
|
||||
filename=$(basename $FILE)
|
||||
extension=${filename##*.}
|
||||
filename=${filename%.*}
|
||||
|
||||
echo "Transcoding file $FILE" >> $LOG
|
||||
if [ "$HAS_NICE_TITLE" = true ]; then
|
||||
echo "transcoding with a nice title" >> "$LOG"
|
||||
DEST="${ARMPATH}/${LABEL}"
|
||||
echo "dest ${DEST} variable created"
|
||||
if [ -d "$DEST" ]; then
|
||||
echo "directory already exists... adding timestamp" >> "$LOG"
|
||||
DEST="${ARMPATH}/${LABEL}_${TIMESTAMP}"
|
||||
fi
|
||||
else
|
||||
echo "transcoding without a nice title" >> "$LOG"
|
||||
DEST="${ARMPATH}/${LABEL}_${TIMESTAMP}"
|
||||
fi
|
||||
|
||||
$HANDBRAKE_CLI -i $SRC/$FILE -o $DEST/$filename.$DEST_EXT --preset="$HB_PRESET" --subtitle scan -F 2> $LOG
|
||||
#TIMESTAMP=`date '+%Y_%m_%d__%H_%M_%S'`;
|
||||
#mv $SRC/$FILE $SRC/done/$TIMESTAMP.$FILE
|
||||
#mv $DEST/$FILE $DEST/done/$FILE
|
||||
rm $SRC/$FILE
|
||||
# DEST="${ARMPATH}/${LABEL}_${TIMESTAMP}"
|
||||
mkdir -p "$DEST"
|
||||
if [ "$SKIP_TRANSCODE" = true ] && [ "$RIPMETHOD" = "mkv" ]; then
|
||||
# this only works for files ripped by MakeMKV into .mkv files
|
||||
echo "Skipping transcode. Moving files from $SRC to $DEST" >> "$LOG"
|
||||
mv "$SRC"/* "$DEST"/ >> "$LOG"
|
||||
elif [ "$RIPMETHOD" = "backup" ] && [ "$MAINFEATURE" = true ] && [ "$ID_CDROM_MEDIA_BD" = "1" ]; then
|
||||
echo "Transcoding BluRay main feature only." >> "$LOG"
|
||||
# shellcheck disable=SC2086
|
||||
$HANDBRAKE_CLI -i "$SRC" -o "$DEST/$LABEL.$DEST_EXT" --main-feature --preset="$HB_PRESET" $HB_ARGS 2>> "$LOG"
|
||||
rmdir "$SRC"
|
||||
elif [ "$RIPMETHOD" = "backup" ] && [ "$MAINFEATURE" = false ] && [ "$ID_CDROM_MEDIA_BD" = "1" ]; then
|
||||
echo "Transcoding BluRay all titles above minlength." >> "$LOG"
|
||||
# Itterate through titles of MakeMKV backup
|
||||
# First check if this is the main title
|
||||
MAINTITLENO="$(echo ""|HandBrakeCLI --input "$SRC" --title 0 --scan |& grep -B 1 "Main Feature" | sed 's/[^0-9]*//g')"
|
||||
|
||||
done
|
||||
# Get number of titles
|
||||
TITLES="$(echo ""|HandBrakeCLI --input "$SRC" --scan |& grep -Po '(?<=scan: BD has )([0-9]+)')"
|
||||
echo "$TITLES titles on BluRay Disc" >> "$LOG"
|
||||
|
||||
rmdir $SRC
|
||||
for TITLE in $(seq 1 "$TITLES")
|
||||
do
|
||||
echo "Processing title $TITLE" >> "$LOG"
|
||||
|
||||
echo /opt/arm/notify.sh "\"Transcode: ${ID_FS_LABEL} complete.\"" |at now
|
||||
TIME="$(echo ""|HandBrakeCLI --input "$SRC" --title "$TITLE" --scan |& grep 'duration is' | sed -r 's/.*\((.*)ms\)/\1/')"
|
||||
|
||||
SEC=$(( TIME / 1000 )) >> "$LOG"
|
||||
echo "Title length is $SEC seconds." >> "$LOG"
|
||||
if [ $SEC -gt "$MINLENGTH" ]; then
|
||||
echo "HandBraking title $TITLE"
|
||||
# shellcheck disable=SC2086
|
||||
$HANDBRAKE_CLI -i "$SRC" -o "$DEST/$LABEL-$TITLE.$DEST_EXT" --min-duration="$MINLENGTH" -t "$TITLE" --preset="$HB_PRESET" $HB_ARGS 2 >> "$LOG"
|
||||
|
||||
# Check for main title and rename
|
||||
if [ "$MAINTITLENO" = "$TITLE" ] && [ "$HAS_NICE_TITLE" = true ]; then
|
||||
echo "Sending the following command: mv -n \"$DEST/$LABEL-$TITLE.$DEST_EXT\" \"${DEST}/${LABEL}.${DEST_EXT}\"" >> "$LOG"
|
||||
mv -n "$DEST/$LABEL-$TITLE.$DEST_EXT" "${DEST}/${LABEL}.${DEST_EXT}" >> "$LOG"
|
||||
fi
|
||||
else
|
||||
echo "Title $TITLE lenth less than $MINLENGTH. Skipping." >> "$LOG"
|
||||
fi
|
||||
done
|
||||
rm -rf "$SRC"
|
||||
elif [ "$MAINFEATURE" = true ] && [ "$ID_CDROM_MEDIA_DVD" = "1" ]; then
|
||||
echo "Transcoding DVD main feature only." >> "$LOG"
|
||||
# echo "$HANDBRAKE_CLI -i $DEVNAME -o \"${DEST}/${LABEL}.${DEST_EXT}\" --main-feature --preset="${HB_PRESET}" --subtitle scan -F 2" >> $LOG
|
||||
# shellcheck disable=SC2086
|
||||
$HANDBRAKE_CLI -i "$DEVNAME" -o "${DEST}/${LABEL}.${DEST_EXT}" --main-feature --preset="${HB_PRESET}" $HB_ARGS 2>> "$LOG"
|
||||
eject "$DEVNAME"
|
||||
else
|
||||
echo "Transcoding all files." >> "$LOG"
|
||||
# shellcheck disable=SC2045
|
||||
for FILE in $(ls "$SRC")
|
||||
do
|
||||
filename=$(basename "$FILE")
|
||||
|
||||
#extension=${filename##*.}
|
||||
filename=${filename%.*}
|
||||
|
||||
echo "Transcoding file $FILE" >> "$LOG"
|
||||
# shellcheck disable=SC2086
|
||||
$HANDBRAKE_CLI -i "$SRC/$FILE" -o "$DEST/$filename.$DEST_EXT" --preset="$HB_PRESET" $HB_ARGS 2>> "$LOG"
|
||||
rm "$SRC/$FILE"
|
||||
done
|
||||
rmdir "$SRC"
|
||||
fi
|
||||
|
||||
embyrefresh ()
|
||||
{
|
||||
ApiKey="$(curl -s -H "Authorization: MediaBrowser Client=\"$EMBY_CLIENT\", Device=\"$EMBY_DEVICE\", DeviceId=\"$EMBY_DEVICEID\", Version=1.0.0.0, UserId=\"$EMBY_USERID\"" -d "username=$EMBY_USERNAME" -d "password=$EMBY_PASSWORD" "http://$EMBY_SERVER:$EMBY_PORT/users/authenticatebyname?format=json" | python -m json.tool | grep 'AccessToken' | sed 's/\"//g; s/AccessToken://g; s/\,//g; s/ //g')"
|
||||
|
||||
RESPONSE=$(curl -d 'Library' "http://$EMBY_SERVER:$EMBY_PORT/Library/Refresh?api_key=$ApiKey")
|
||||
|
||||
if [ ${#RESPONSE} = 0 ]; then
|
||||
# scan was successful
|
||||
echo "Emby refresh command sent successfully" >> "$LOG"
|
||||
else
|
||||
# scan failed
|
||||
echo "Emby refresh command failed for some reason. Probably authentication issues" >> "$LOG"
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$VIDEO_TYPE" = "movie" ] && [ "$MAINFEATURE" = true ] && [ "$HAS_NICE_TITLE" = true ] && [ "$EMBY_SUBFOLDERS" = false ]; then
|
||||
# move the file to the final media directory
|
||||
# shellcheck disable=SC2129,SC2016
|
||||
echo '$VIDEO_TYPE is movie, $MAINFEATURE is true, $HAS_NICE_TITLE is true, $EMBY_SUBFOLDERS is false' >> "$LOG"
|
||||
echo "Moving a single file." >> "$LOG"
|
||||
echo "Checing for existing file..." >> "$LOG"
|
||||
if [ ! -f "$MEDIA_DIR/$LABEL.$DEST_EXT" ]; then
|
||||
echo "No file found. Moving \"$DEST/$LABEL.$DEST_EXT to $MEDIA_DIR/$LABEL.$DEST_EXT\"" >> "$LOG"
|
||||
mv -n "$DEST/$LABEL.$DEST_EXT" "$MEDIA_DIR/$LABEL.$DEST_EXT"
|
||||
|
||||
if [ "$SET_MEDIA_PERMISSIONS" = true ]; then
|
||||
|
||||
chmod -R "$CHMOD_VALUE" "$MEDIA_DIR"
|
||||
|
||||
fi
|
||||
|
||||
if [ "$EMBY_REFRESH" = true ]; then
|
||||
# signal emby to scan library
|
||||
embyrefresh
|
||||
else
|
||||
echo "Emby Refresh False. Skipping library scan" >> "$LOG"
|
||||
fi
|
||||
else
|
||||
echo "Warning: $MEDIA_DIR/$LABEL.$DEST_EXT File exists! File moving aborted" >> "$LOG"
|
||||
fi
|
||||
elif [ "$VIDEO_TYPE" = "movie" ] && [ "$MAINFEATURE" = true ] && [ "$HAS_NICE_TITLE" = true ] && [ "$EMBY_SUBFOLDERS" = true ]; then
|
||||
# shellcheck disable=SC2129,SC2016
|
||||
echo '$VIDEO_TYPE is movie, $MAINFEATURE is true, $HAS_NICE_TITLE is true, $EMBY_SUBFOLDERS is true' >> "$LOG"
|
||||
echo "Moving a single file to emby subfolders" >> "$LOG"
|
||||
mkdir -p "$MEDIA_DIR/$LABEL" >> "$LOG"
|
||||
if [ ! -f "$MEDIA_DIR/$LABEL/$LABEL.$DEST_EXT" ]; then
|
||||
echo "No file found. Moving \"$DEST/$LABEL.$DEST_EXT to $MEDIA_DIR/$LABEL/$LABEL.$DEST_EXT\"" >> "$LOG"
|
||||
mv -n "$DEST/$LABEL.$DEST_EXT" "$MEDIA_DIR/$LABEL/$LABEL.$DEST_EXT"
|
||||
|
||||
if [ "$SET_MEDIA_PERMISSIONS" = true ]; then
|
||||
|
||||
chmod -R "$CHMOD_VALUE" "$MEDIA_DIR/$LABEL"
|
||||
|
||||
fi
|
||||
|
||||
if [ "$EMBY_REFRESH" = true ]; then
|
||||
# signal emby to scan library
|
||||
embyrefresh
|
||||
else
|
||||
echo "Emby Refresh False. Skipping library scan" >> "$LOG"
|
||||
fi
|
||||
else
|
||||
echo "Warning: $MEDIA_DIR/$LABEL/$LABEL.$DEST_EXT File exists! File moving aborted" >> "$LOG"
|
||||
fi
|
||||
elif [ "$VIDEO_TYPE" = "movie" ] && [ "$MAINFEATURE" = false ] && [ "$HAS_NICE_TITLE" = true ] && [ "$EMBY_SUBFOLDERS" = false ]; then
|
||||
# shellcheck disable=SC2129,SC2016
|
||||
echo '$VIDEO_TYPE is movie, $MAINFEATURE is false, $HAS_NICE_TITLE is true, $EMBY_SUBFOLDERS is false' >> "$LOG"
|
||||
# hopefully this is never happen because it will cause a lot of duplicate files
|
||||
echo "***WARNING!*** This will likely leave files in the transcoding directory as there is very likely existing files in the media directory"
|
||||
echo "Moving multiple files to emby movie folder" >> "$LOG"
|
||||
mv -n "$DEST/$LABEL.$DEST_EXT" "$MEDIA_DIR/$LABEL.$DEST_EXT"
|
||||
|
||||
if [ "$SET_MEDIA_PERMISSIONS" = true ]; then
|
||||
|
||||
chmod -R "$CHMOD_VALUE" "$MEDIA_DIR"
|
||||
|
||||
fi
|
||||
|
||||
if [ "$EMBY_REFRESH" = true ]; then
|
||||
# signal emby to scan library
|
||||
embyrefresh
|
||||
else
|
||||
echo "Emby Refresh False. Skipping library scan" >> "$LOG"
|
||||
fi
|
||||
elif [ "$VIDEO_TYPE" = "movie" ] && [ "$MAINFEATURE" = false ] && [ "$HAS_NICE_TITLE" = true ] && [ "$EMBY_SUBFOLDERS" = true ]; then
|
||||
# shellcheck disable=SC2129,SC2016
|
||||
echo '$VIDEO_TYPE is movie, $MAINFEATURE is false, $HAS_NICE_TITLE is true, $EMBY_SUBFOLDERS is true' >> "$LOG"
|
||||
echo "Moving multiple files to emby movie subfolders" >> "$LOG"
|
||||
echo "First move main title" >> "$LOG"
|
||||
mkdir -p -v "$MEDIA_DIR/$LABEL" >> "$LOG"
|
||||
if [ ! -f "$MEDIA_DIR/$LABEL/$LABEL.$DEST_EXT" ]; then
|
||||
echo "No file found. Moving \"$DEST/$LABEL.$DEST_EXT to $MEDIA_DIR/$LABEL/$LABEL.$DEST_EXT\"" >> "$LOG"
|
||||
mv -n "$DEST/$LABEL.$DEST_EXT" "$MEDIA_DIR/$LABEL/$LABEL.$DEST_EXT" >> "$LOG"
|
||||
|
||||
if [ "$SET_MEDIA_PERMISSIONS" = true ]; then
|
||||
|
||||
chmod -R "$CHMOD_VALUE" "$MEDIA_DIR/$LABEL"
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
#now move "extras"
|
||||
if [ "$PLEX_SUPPORT" = true ]; then
|
||||
|
||||
# shellcheck disable=SC2129,SC2016
|
||||
mkdir -p -v "$MEDIA_DIR/$LABEL/Featurettes" >> "$LOG"
|
||||
|
||||
# Create Emby ignore file for "extras" Folder
|
||||
touch "$MEDIA_DIR/$LABEL/Featurettes/.ignore" >> "$LOG"
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
echo "Sending command: mv -n "\"$DEST/$LABEL/*\"" "\"$MEDIA_DIR/$LABEL/Featurettes/\""" >> "$LOG"
|
||||
mv -n "${DEST}"/* "$MEDIA_DIR/$LABEL/Featurettes/" >> "$LOG"
|
||||
|
||||
# Move Largest file to main folder for Plex/Emby/Kodi to detect main movie
|
||||
# shellcheck disable=SC2012
|
||||
ls -S "$MEDIA_DIR/$LABEL/Featurettes/" | head -1 | xargs -I '{}' mv "$MEDIA_DIR/$LABEL/Featurettes/"{} "$MEDIA_DIR/$LABEL/$LABEL.mkv" >> "$LOG"
|
||||
|
||||
if [ "$SET_MEDIA_PERMISSIONS" = true ]; then
|
||||
|
||||
chmod -R "$CHMOD_VALUE" "$MEDIA_DIR/$LABEL"
|
||||
|
||||
fi
|
||||
else
|
||||
|
||||
# shellcheck disable=SC2129,SC2016
|
||||
mkdir -p -v "$MEDIA_DIR/$LABEL/extras" >> "$LOG"
|
||||
|
||||
# Create Plex ignore file for "extras" Folder
|
||||
touch "$MEDIA_DIR/$LABEL/extras/.plexignore" >> "$LOG"
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
echo "Sending command: mv -n "\"$DEST/$LABEL/*\"" "\"$MEDIA_DIR/$LABEL/extras/\""" >> "$LOG"
|
||||
mv -n "${DEST}"/* "$MEDIA_DIR/$LABEL/extras/" >> "$LOG"
|
||||
|
||||
# Move Largest file to main folder for Plex/Emby/Kodi to detect main movie
|
||||
# shellcheck disable=SC2012
|
||||
ls -S "$MEDIA_DIR/$LABEL/extras/" | head -1 | xargs -I '{}' mv "$MEDIA_DIR/$LABEL/extras/"{} "$MEDIA_DIR/$LABEL/$LABEL.mkv" >> "$LOG"
|
||||
|
||||
if [ "$SET_MEDIA_PERMISSIONS" = true ]; then
|
||||
|
||||
chmod -R "$CHMOD_VALUE" "$MEDIA_DIR/$LABEL"
|
||||
|
||||
fi
|
||||
|
||||
if [ "$EMBY_REFRESH" = true ]; then
|
||||
# signal emby to scan library
|
||||
embyrefresh
|
||||
else
|
||||
echo "Emby Refresh False. Skipping library scan" >> "$LOG"
|
||||
fi
|
||||
|
||||
fi
|
||||
rmdir "$DEST"
|
||||
fi
|
||||
|
||||
rmdir "$SRC"
|
||||
|
||||
TRANSEND=$(date +%s);
|
||||
TRANSSEC=$((TRANSEND-TRANSSTART));
|
||||
TRANSTIME="$((TRANSSEC / 3600)) hours, $(((TRANSSEC / 60) % 60)) minutes and $((TRANSSEC % 60)) seconds."
|
||||
|
||||
echo "STAT: ${ID_FS_LABEL} transcoded in ${TRANSTIME}" >> "$LOG"
|
||||
|
||||
#echo /opt/arm/rename.sh $DEST
|
||||
|
||||
echo /opt/arm/notify.sh "\"Transcode: ${ID_FS_LABEL} completed in ${TRANSTIME}\"" |at now
|
||||
|
||||
Reference in New Issue
Block a user