135 lines
7.0 KiB
Org Mode
Executable File
135 lines
7.0 KiB
Org Mode
Executable File
#+TITLE: DVD Rip
|
|
#+OPTIONS: toc:2
|
|
|
|
Some scripts to automate ripping and transcoding of your DVDs (movies or series) into video files.
|
|
Note this is most efficient digitizing TV series and/or large amounts of movies.
|
|
|
|
If you only have a few movies you want digitized, I recommend using [[https://handbrake.fr/][Handbrake]] to do it manually.
|
|
|
|
* How it works
|
|
This project is divided in two separate parts, the =ripper= and the =transcoder=.
|
|
|
|
The idea is to clone this project to your local machine, then run the =ripper= manually, which just copies the inserted DVD.
|
|
Then you =transfer= the files to the =transcoder=.
|
|
The transcoder can also be on your local machine, or you can have this project cloned onto a server, which then does the transcoding automatically 24/7.
|
|
|
|
** Ripping
|
|
To do the ripping, enter the =ripper= directory and run ~./rip_dvd.py <args>~.
|
|
The most important argument is the type of the DVD, either =movie= or =series=, and the name of the movie or TV series you are ripping.
|
|
|
|
*Directory structure:*
|
|
#+begin_example
|
|
./ripper
|
|
├── bell.oga # The sound to be played when ripping has finished
|
|
├── rip_dvd.py # The ripper script
|
|
├── rip.log # Logs all ripping attempts
|
|
├── ripped
|
|
│ ├── movie # The ripped movies
|
|
│ └── series # The ripped series
|
|
├── tmp # The ripped files while ripping has not yet finished.
|
|
│ # If the script has been terminated, this might not get deleted.
|
|
│ # In this case just remove it yourselves.
|
|
└── transfer_ripped.py # The transfer script
|
|
#+end_example
|
|
|
|
** Transfer
|
|
To transfer the ripped files to the transcoder, enter the =ripper= directory and run ~./transfer_ripped.py~.
|
|
This will rsync all the ripped files to the ~TRANSFER_DESTINATION_FOLDER~ (see [[*Configuration][Configuration]]) which may be on an external server which then will transcode them into video files.
|
|
|
|
Note while the transfer is in progress, the script will create =movie_title.lock= files in source and destination folder to indicate the transfer is yet incomplete.
|
|
The transcoder will not try to transcode data for which the =.lock= file exists.
|
|
|
|
** Transcoding
|
|
To transcode the ripped files, enter the =transcoder= directory, then run ~./transcode_dvd.py~.
|
|
This will try to transcode all the files in the =raw= folder and put the results in the =transcoded= folder.
|
|
While transcoding is in progress, you can see the live log produced by handbrake by running ~tail -f raw/movie_title.log~.
|
|
|
|
You can also run this in a systemd-service. For this see the =video_transcoder.service.sample= file.
|
|
|
|
*Directory structure:*
|
|
#+begin_example
|
|
./transcoder
|
|
├── transcode_dvd.py # The transcode script
|
|
├── transcode.log # Logs all transcoding attempts
|
|
├── raw # The transfer_ripped.py script should transfer all ripped files here
|
|
│ ├── movie
|
|
│ └── series
|
|
├── transcoded
|
|
│ ├── movie # The transcoded movies
|
|
│ └── series # The transcoded series
|
|
├── tmp # The transcoded files while transcoding has not yet finished.
|
|
│ # In case of an error during transcoding, this might not get deleted.
|
|
│ # In this case just remove it yourselves.
|
|
└── video_transcoder.service.sample # The sample systemd service file
|
|
#+end_example
|
|
|
|
*** Fixing transcoding errors
|
|
When there was an error transcoding you will see an =movie_title.err.log= file in the =raw= folder.
|
|
This will include the handbrake logs telling you what has gone wrong.
|
|
After you have fixed the error, delete the =movie_title.err.log= file and the transcoder will re-attempt transcoding of the movie on the next run.
|
|
|
|
**** Fixing Handbrake Error 5
|
|
Sometimes when a dvd is damaged, handbrake will exit in the mid of transcoding, resulting in a video file with only a part of the movie.
|
|
When this happened, handbrake wrote =Encode failed (error 5)= into the log.
|
|
|
|
For me, using the option ~--no-dvdnav~ resulted in the full video being transcoded (note the damaged parts will not be fixed).
|
|
To tell the transcoder to use this option, just create an empty =series_or_movie_title.nodvdnav= file in the =raw= folder.
|
|
|
|
**** Fixing series errors
|
|
When transcoding TV series, a common error is that there are more video tracks on the DVD than you specified there are episodes on the DVD.
|
|
Whether this is the case, you can see at the bottom of the =series_title.err.log= file.
|
|
|
|
To fix this, find out which tracks correspond to the episodes on the DVD, then create a =series_title.titles= file in the =raw= folder.
|
|
In this file specify the track numbers one per line.
|
|
|
|
*Example:* your series file is called =Lost_S01_E01-04=, but the DVD has 5 tracks.
|
|
Assuming track 1 is just a bonus scene you do not want transcoded, create =Lost_S01_E01-04.titles=:
|
|
|
|
#+begin_example
|
|
2
|
|
3
|
|
4
|
|
5
|
|
#+end_example
|
|
|
|
Then delete the =Lost_S01_E01-04.err.log= file and the transcoder will retry the transcoding using just titles 2-5 on its next run.
|
|
|
|
**** About movie transcoding errors
|
|
To automate the DVD-transcoding, this project will tell handbrake to find the main title of the DVD and transcode it.
|
|
The detection of the main title can sometimes fail resulting in some other DVD title being transcoded.
|
|
|
|
This means there is no guarantee that transcoding works for every movie (though in my case it worked for about 90%) and you should check all resulting video files.
|
|
In case of a failure it is fastest to rip and transcode the DVD manually with handbrake.
|
|
|
|
* Configuration
|
|
Configuration is done via an =.env= file. For this, just do ~cp .env.sample .env~ and edit the =.env= file to your liking.
|
|
When using an server for transcoding, edit the =TRANSFER_DESTINATION_FOLDER= value.
|
|
Its default is to transfer the files to the =transcoder/raw= folder of the current project.
|
|
|
|
* Dependencies
|
|
- dvdbackup (=ripper=)
|
|
- rsync (=ripper=)
|
|
- libnotify (=ripper=)
|
|
- handbrake (=transcoder=)
|
|
- python3 with dependencies listed in =requirements.txt= (=both=)
|
|
|
|
** Nix dev-shell
|
|
If you use nix you can use the =flake.nix= via ~nix develop~ to enter a shell environment with all the dependencies satisfied.
|
|
In case you also use direnv, just run ~direnv allow .~ to automatically enter the environment whenever entering the project directory.
|
|
|
|
* License
|
|
#+begin_quote
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
#+end_quote
|