Determine optical media type (Audio CD, DVD, blu-ray) by using UDEV and scripts
Asked Answered
J

2

17

I am relatively new to linux having made the switch from Windows to have a headless media centre. I am running KODIBuntu.

I am trying to achieve an automated ripping system to backup my hard copy media collection. I have loved the concept with linux that 'if you can dream it you can make it happen'.

What I'm aiming to achieve is that a disc is put into the drive and a script rips the content to my drive.

e.g disc inserted -> media type determined -> correct ripping script run

I have used lots of useful web pages through google searches to create scripts that will do the ripping work itself. I have done a bunch of reading and was pointed towards using 'HAL'....I then found that his function had been deprecated and replaced by udev. I did a bunch more reading and found out how to use UDEV and created the folowing rule which i have proved works by linking directly to a ripping script

    ACTION=="change", SUBSYSTEMS=="scsi", KERNEL=="s[rg][0-9]*", ATTRS{vendor}=="TSSTcorp", MODE="0660", GROUP="optical", RUN+="/home/jlivin25/myscripts/DiscTypeTest.sh"

I realised that I needed an intermediate script that would do the 'work' to determine what the optical media type is. Further reading led me to believe that I would need to use some kind of 'IF' statement.

IF disc inserted then IF audio cd run rip script 1 IF DVD run rip script 2 IF blu-ray run rip script 3 ELSE no cd inserted

I have done some more googling and found some code in various places that uses environmental variables to work. However from further information on google it appears that these variables are not defined until referenced by UDEV?

My usual approach is to constuct a line of code, run in terminal and if i get what i want then i put all the lines together in a shell script?

The code i am working on a the moment is below. I though that logically if i could get the script to output what it thinks is in the drive to a file /log that half the battle would be won and i could just substitute this for the script locations that would do the corresponding ripping task ... any ideas folks about why this is not working as i want?

I have used these pages to get information from:

here is my code:

#!/bin/bash
#
set -eu
#
# code below is derived from work by JimVanns, thanks
# https://github.com/jvanns/htpc/blob/master/dsc-trg-q
#
#
###########################################################################
###                        DEFINE VARIABLES HERE                        ###
### $HOME DOES NOT NEED DEFINING AS IT SEEMS TO BE BUILT INTO BASH FROM ###
###   WHAT POSTS I HAVE READ RELATING TO USING WHAT I THINK ARE UDEV    ###
###  ENVIRONMENTAL VARIABLES E.G. $ID_CDROM_MEDIA_CD DO NOT APPEAR TO   ###
###    NEED DEFINING THEMSELVES, ALSO PART OF BASH OR LINUX COMMAND     ###
###                      STRUCTURE CALLED BY BASH?                      ###
###########################################################################
#
MEDIA=
#
##############################################################################
### LEFT IN SO AS TO ALTER AS LITTLE AS POSSIBLE, I HAVE READ THAT DELAYS  ###
###  OFTEN IRON OUT KINKS IN CODE,  PLUS ALSO FOUND IT USEFULL TO ALLOW A  ###
###    SMALL DELAY FOR CD-DRIVE TO DO ITS THING AFTER PUTTING DISK IN      ###
##############################################################################
#
sleep 2
#
mkdir -p $HOME/myscripts/scriptlogs
#
#
if [ "$ID_CDROM_MEDIA_BD" = "1" ]
then
    MEDIA=bluray
    (
    echo "$MEDIA" >> $HOME/myscripts/scriptlogs/DiscTypeTest.log
    ) &
if [ "$ID_CDROM_MEDIA_DVD" = "1" ]
then
    MEDIA=dvd
    (
    echo "$MEDIA" >> $HOME/myscripts/scriptlogs/DiscTypeTest.log
    ) &
elif [ "$ID_CDROM_MEDIA_CD" = "1" ]
then
    MEDIA=cdrom
    (
    echo "$MEDIA" >> $HOME/myscripts/scriptlogs/DiscTypeTest.log
    ) &
fi
Jp answered 30/4, 2015 at 17:11 Comment(1)
the links are not working.Birgitbirgitta
B
5

The variables are not set anywhere.

Usually this is asetting in udev startup rule ( in /usr/lib/udev/rules.d/ ), and looks somewhat like

# ID_CDROM_MEDIA_BD = Bluray
# ID_CDROM_MEDIA_DVD = DVD
# ID_CDROM_MEDIA_CD = CD
SUBSYSTEM=="scsi", KERNEL=="sr0", ENV{ID_CDROM_MEDIA_BD}=="1", RUN+="/home/user/ripping_script.sh"

Since udev doesn't know about the media-type in advance , this is manually set as a environment variable. But since you want to automatically start a different script on certain conditions, this is not useful.

However, you can determine and set the mediatype variables in the ripping script also:

first install cdtool , it can give you some info on audio CD's (with cdir). sudo apt-get install cdtool

Add this to the beginning of your script:

#!/bin/bash
# ripping_script.sh

CDDVD=`cdir -vd /dev/sr0  2>&1 |grep -q "no_disc" || echo "cd"`

if [ $CDDVD ]; then
 ID_CDROM_MEDIA_CD=1
 echo "CD detected" >> $HOME/myscripts/scriptlogs/rip.log  
else
 ID_CDROM_MEDIA_DVD=1         
 echo "DVD detected" >> $HOME/myscripts/scriptlogs/rip.log 
fi


# ... your rippingscript here 

/dev/sr0 is most likely your cd/dvd.

this only differentiates between audioCD and DVD. I don't have any blu-ray stuff for tests.

Birgitbirgitta answered 5/5, 2015 at 10:16 Comment(5)
hello lxer thanks very much for taking the time to answer. I will certainly try what you suggest to see if it gives me a useable outcome, i'd not come accross cdtool. Sticking to my first post any ideas why the environmental variables are not working for me as is? or even how to test to see whats not working?Jp
the environment variables are not set. I updated updated the answer to include it.Birgitbirgitta
Thanks i really appreciate the explanation...I think i'm starting to see light at the end of the tunnel. Is it that I need to adjust my thinking slightly so that i have a three udev rules. Lets say 80-bluray.rule , 81-dvd.rule and 82-cd.rule then use your example to populate the udev rules accordingly. so rule 80 would be SUBSYSTEM=="scsi", KERNEL=="sr0", ENV{ID_CDROM_MEDIA_BD}=="1", RUN+="/home/user/BLURip.sh" rule 81 would be SUBSYSTEM=="scsi", KERNEL=="sr0", ENV{ID_CDROM_MEDIA_DVD}=="1", RUN+="/home/user/DVDRip.sh" etc..Jp
yes, but no. If you do that then all 3 rules would just get started every time you put a cd in the device, so not what you want. (however, if you have 3 different dedicated drives you could do it, but you'd also have to set sr0, sr1, sr2). Just put my code at the beginning of your script, then the correct variable for the mediatype is set (ID_CDROM_MEDIA_DVD or ID_CDROM_MEDIA_CD) .Birgitbirgitta
ahhhh i think i see....so shebang as usual then # ID_CDROM_MEDIA_DVD = DVD # ID_CDROM_MEDIA_CD = CD followed by rest of script with the commented out variables making sure they are availible for the script to use? ...will try this tonight. ThanksJp
J
1

Solved!

Udev rule looks like this.

# ID_CDROM_MEDIA_BD = Bluray
# ID_CDROM_MEDIA_DVD = DVD
# ID_CDROM_MEDIA_CD = CD
ACTION=="change", SUBSYSTEMS=="scsi", KERNEL=="s[rg][0-9]*",  ATTRS{vendor}=="TSSTcorp", ENV{ID_CDROM}=="?*", MODE="0660", GROUP="optical", RUN+="/usr/local/bin/DiscTypeTest3.sh"

and script to trigger ripping scripts looks like this:

#!/bin/bash
# ID_CDROM_MEDIA_BD = Bluray
# ID_CDROM_MEDIA_DVD = DVD
# ID_CDROM_MEDIA_CD = CD
MEDIA=
if [ $ID_CDROM_MEDIA_DVD = "1" ]
   then
   MEDIA=dvd
   (
   echo "$MEDIA" >> "/var/log/DiscTypeTest.log"
   ) &
elif [ $ID_CDROM_MEDIA_CD = "1" ]
    then
    MEDIA=cdrom
    (
    echo "$MEDIA" >> "/var/log/DiscTypeTest.log"
    ) &
fi
(set -o posix ; set) > "/var/log/DiscTypeTestVariables.log"

This results in the following output to log file when a audio cd is inserted followed by a dvd

cdrom
cdrom
dvd
dvd

Replacing the echo lines with the path to ripping scripts should result in automated headless system as desired

Credit goes to Jim Vanns for code, Keith_Helms and blm_ubunet on ubuntu forums for posix code and corrections to if statements and Ixer here for the variable pointers

Hope this helps

James

Jp answered 15/5, 2015 at 16:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.