Showing posts with label cli. Show all posts
Showing posts with label cli. Show all posts

Monday, April 18, 2011

So my buddy over at Forshee Media was asking me the other day if I could build him a DVD duplicator on the cheap. I said “Challenge Accepted”. Here's how I did it.

The Hardware

Being a guy that works in the IT field, I get a lot of junk or old systems donated to me. I had plenty of parts sitting around to build a decently running, purpose built appliance like this, but I wouldn't want to use systems with their specs for a main desktop. Here are the specs:

  • Pentium 4 processor
  • 512MB PC2-3200
  • 1 – 80GB PATA Drive for the OS
  • Motherboard with 4 SATA ports
  • 2 PATA connectors
  • Case with at least 4-5.25” drive bays

Sounds pretty simple right? I also had a few DVD burners sitting around that I could use to test the software. I didn't have the 4 burners that he wanted but the software would scale.

The Software

I installed Ubuntu 10.10 Server Edition on it because it takes up very few resources. This device will have nothing but a power cord and a network cable hooked to it. As such, it will be remotely controlled via ssh.

The network card has everything statically assigned. I got some of my buddy's network specs ahead of time. How this can be accomplished is edit /etc/network/interfaces and here is what I added to his configuration:

iface eth0 inet static
address 192.168.1.200
netmask 255.255.255.0
gateway 192.168.1.1

Pretty simple. With an “apt-get install ssh”, I unhooked all of the peripherals and ran this thing like the headless drone it is supposed to be.

Up next was finding out what DVD drives are being recognized. This is important as the dev assignments are statically coded into the coming scripts. To find out what drives are available “udisks --enumerate | grep sr”. Normally optical drives are specified with an sr#. Your distro might vary.

The Code

Now we're getting to the good part. The meat and potatoes of this operation. Here is a script that works for me with 4 drives:

#!/bin/bash

dvd1=/dev/sr0
dvd2=/dev/sr1
dvd3=/dev/sr2
dvd4=/dev/sr3

dvd_prep(){
    local dvd_to_load=$1
    local state=$2
    dvd_load=0
    sleep 2
    while [ $dvd_load -eq 0 ]
    do
        dvd_load=`udisks --show-info $dvd_to_load | grep -c "blank: *$state"`
    done
}

echo "Load DVD into top tray"
eject $dvd1
dvd_prep $dvd1 0
echo "Copying DVD to image"
dd if=$dvd1 of=dvdimage.iso bs=512
eject $dvd1

echo "How many copies?"
read copies
count=1
while [ $count -le $copies ]
do
    remaining=0
    if [ $copies -gt 1 ]
    then
        remaining=$((copies-count))
    fi

    if [ $copies -eq 1 -o $remaining -eq 0 ]
    then
        dvd_prep $dvd1 1
        echo "Number $count"
        eject $dvd1
        growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd1=dvdimage.iso > duplicator_log 
        eject $dvd1
        let "count+=1"

    elif [ $copies -eq 2 -o $remaining -eq 1 ]
        eject $dvd1
        eject $dvd2
       
        dvd_prep $dvd1 1
        echo "Number $count"
        let "count+=1"

        dvd_prep $dvd2 1
        echo "Number $count"
        let "count+=1"
        growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd1=dvdimage.iso  > duplicator_log  && eject $dvd1 & growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd2=dvdimage.iso  > duplicator_log && eject $dvd2 

    elif [ $copies -eq 3 -o $remaining -eq 2 ]
        eject $dvd1
        eject $dvd2
        eject $dvd3
       
        dvd_prep $dvd1 1
        echo "Number $count"
        let "count+=1"

        dvd_prep $dvd2 1
        echo "Number $count"
        let "count+=1"

        dvd_prep $dvd3 1
        echo "Number $count"
        let "count+=1"

        growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd1=dvdimage.iso  > duplicator_log  && eject $dvd1 & growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd2=dvdimage.iso  > duplicator_log && eject $dvd3 & growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd3=dvdimage.iso  > duplicator_log && eject $dvd3    
    else
        eject $dvd1
        eject $dvd2
        eject $dvd3
        eject $dvd4
       
        dvd_prep $dvd1 1
        echo "Number $count"
        let "count+=1"

        dvd_prep $dvd2 1
        echo "Number $count"
        let "count+=1"

        dvd_prep $dvd3 1
        echo "Number $count"
        let "count+=1"

        dvd_prep $dvd4 1
        echo "Number $count"
        let "count+=1"

        growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd1=dvdimage.iso  > duplicator_log  && eject $dvd1 & growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd2=dvdimage.iso  > duplicator_log && eject $dvd3 & growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd3=dvdimage.iso  > duplicator_log && eject $dvd3  & growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd4=dvdimage.iso  > duplicator_log && eject $dvd4 
    fi
done
echo "Done"
rm dvdimage.iso


All This does is copy DVDs. If it's worth doing, it's worth doing overkill. That being said...

LightScribe

Since the drives I bought for this project are LightScribe compatible, I decided to write a bit more in this script in order to turn this not only into a DVD toaster, but also make mass LightScribe operations possible. Doing more than, say, 5 of the same LS label is tedious.

Get this label here
I found that you need to have the LightScribe System software installed as well as the Lacie LS Utilities (because they have a scriptable CLI implementation). It is a bit of a process to get this working, but worth it.

How this works is when the DVD is done being written, the user is prompted to turn the DVD over to etch a bitmap label on the top. The LightScribe bits of this code are activated when the script is fed an argument of an image name without an extension (ex. "./duplicator label" not "./duplicator label.bmp")

Le Code in red is what was changed from the previous code:


#!/bin/bash

LS=$1
dvd1=/dev/sr0
dvd2=/dev/sr1
dvd3=/dev/sr2
dvd4=/dev/sr3

dvd_prep(){
    local dvd_to_load=$1
    local state=$2
    dvd_load=0
    sleep 2
    while [ $dvd_load -eq 0 ]
    do
        dvd_load=`udisks --show-info $dvd_to_load | grep -c "blank: *$state"`
    done
}

ls_prep(){
    local dvd_to_load=$1
    dvd_load=0
    sleep 2
    while [ $dvd_load -eq 0 ]
    do
        dvd_load=`4L-cli mediainfo $dvd_to_load | grep Oriented | cut -d' ' -f4`
    done
}


echo "Load DVD into top tray"
eject $dvd1
dvd_prep $dvd1 0
echo "Copying DVD to image"
dd if=$dvd1 of=dvdimage.iso bs=512
eject $dvd1

echo "How many copies?"
read copies
count=1
while [ $count -le $copies ]
do
    remaining=0
    if [ $copies -gt 1 ]
    then
        remaining=$((copies-count))
    fi

    if [ $copies -eq 1 -o $remaining -eq 0 ]
    then
        dvd_prep $dvd1 1
        echo "Number $count"
        eject $dvd1
        growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd1=dvdimage.iso > duplicator_log

    if [ $LS ]
    then    
        eject $dvd1
        echo "Flip the DVD over and close the drive tray."
        ls_prep $dvd1
        4L-cli print $dvd1 labels/$LS.bmp
    fi

        eject $dvd1
        let "count+=1"

    elif [ $copies -eq 2 -o $remaining -eq 1 ]
        eject $dvd1
        eject $dvd2
     
        dvd_prep $dvd1 1
        echo "Number $count"
        let "count+=1"

        dvd_prep $dvd2 1
        echo "Number $count"
        let "count+=1"
        growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd1=dvdimage.iso  > duplicator_log  && eject $dvd1 &
    growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd2=dvdimage.iso  > duplicator_log && eject $dvd2
  
if [ $LS ]
    then    
        eject $dvd1
        eject $dvd2
        echo "Flip the DVDs over and close the drive trays."
        
        ls_prep $dvd1
        ls_prep $dvd2

        4L-cli print $dvd1 labels/$LS.bmp &
        4L-cli print $dvd2 labels/$LS.bmp
    fi

    elif [ $copies -eq 3 -o $remaining -eq 2 ]
        eject $dvd1
        eject $dvd2
        eject $dvd3
     
        dvd_prep $dvd1 1
        echo "Number $count"
        let "count+=1"

        dvd_prep $dvd2 1
        echo "Number $count"
        let "count+=1"

        dvd_prep $dvd3 1
        echo "Number $count"
        let "count+=1"

        growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd1=dvdimage.iso  > duplicator_log  && eject $dvd1 &
    growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd2=dvdimage.iso  > duplicator_log && eject $dvd3 &
    growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd3=dvdimage.iso  > duplicator_log && eject $dvd3  

    if [ $LS ]
    then    
        eject $dvd1
        eject $dvd2
        eject $dvd3
        echo "Flip the DVDs over and close the drive trays."
        
        ls_prep $dvd1
        ls_prep $dvd2
        ls_prep $dvd3

        4L-cli print $dvd1 labels/$LS.bmp &
        4L-cli print $dvd2 labels/$LS.bmp &
        4L-cli print $dvd3 labels/$LS.bmp
    fi

    else
        eject $dvd1
        eject $dvd2
        eject $dvd3
        eject $dvd4
     
        dvd_prep $dvd1 1
        echo "Number $count"
        let "count+=1"

        dvd_prep $dvd2 1
        echo "Number $count"
        let "count+=1"

        dvd_prep $dvd3 1
        echo "Number $count"
        let "count+=1"

        dvd_prep $dvd4 1
        echo "Number $count"
        let "count+=1"

        growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd1=dvdimage.iso  > duplicator_log  && eject $dvd1 &
    growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd2=dvdimage.iso  > duplicator_log && eject $dvd2 &
    growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd3=dvdimage.iso  > duplicator_log && eject $dvd3
    & growisofs -dvd-compat -use-the-force-luke=bufsize:32m -use-the-force-luke=notray -Z $dvd4=dvdimage.iso  > duplicator_log && eject $dvd4

    if [ $LS ]
    then    
        eject $dvd1
        eject $dvd2
        eject $dvd3
        eject $dvd4
        echo "Flip the DVDs over and close the drive trays."
        
        ls_prep $dvd1
        ls_prep $dvd2
        ls_prep $dvd3
        ls_prep $dvd4

        4L-cli print $dvd1 labels/$LS.bmp &
        4L-cli print $dvd2 labels/$LS.bmp &
        4L-cli print $dvd3 labels/$LS.bmp &
        4L-cli print $dvd4 labels/$LS.bmp
    fi
    fi
done
echo "Done"
rm dvdimage.iso


If you just want a script that will handle Lightscribe and nothing else:

#!/bin/bash

LS=$1
dvd1=/dev/sr0
dvd2=/dev/sr2
dvd3=/dev/sr1
dvd4=/dev/sr3

ls_prep(){
    local dvd_to_load=$1
    media_ready=0
    while [ $media_ready -eq 0 ]   
    do
        media_ready=`4L-cli mediainfo $dvd_to_load | grep media | cut -d' ' -f3`
    done
}

echo "How many copies?"
read copies
count=1
while [ $count -le $copies ]
do
    remaining=0
    if [ $copies -gt 1 ]
    then
        remaining=$((copies-count))
    fi

    if [ $copies -eq 1 -o $remaining -eq 0 ]
    then
        eject $dvd1
        ls_prep $dvd1
        4L-cli print -q best $dvd1 "/home/ftp/$LS.bmp" && eject $dvd1
        echo "Number $count"
        let "count+=1"

    elif [ $copies -eq 2 -o $remaining -eq 1 ]
    then
        eject $dvd1
        eject $dvd2
        ls_prep $dvd1
        echo "Number $count"
        let "count+=1"
        ls_prep $dvd2
        echo "Number $count"
        let "count+=1"
        4L-cli print -q best $dvd1 "/home/ftp/$LS.bmp" && eject $dvd1 &
        4L-cli print -q best $dvd2 "/home/ftp/$LS.bmp" && eject $dvd2

    elif [ $copies -eq 3 -o $remaining -eq 2 ]
    then
        eject $dvd1
        eject $dvd2
        eject $dvd3
        ls_prep $dvd1
        echo "Number $count"
        let "count+=1"
        ls_prep $dvd2
        echo "Number $count"
        let "count+=1"
        ls_prep $dvd3
        echo "Number $count"
        let "count+=1"
        4L-cli print -q best $dvd1 "/home/ftp/$LS.bmp" && eject $dvd1 &
        4L-cli print -q best $dvd2 "/home/ftp/$LS.bmp" && eject $dvd2 &
        4L-cli print -q best $dvd3 "/home/ftp/$LS.bmp" && eject $dvd3

    else
        eject $dvd1
        eject $dvd2
        eject $dvd3
        eject $dvd4

        ls_prep $dvd1
        echo "Number $count"
        let "count+=1"
        ls_prep $dvd2
        echo "Number $count"
        let "count+=1"
        ls_prep $dvd3
        echo "Number $count"
        let "count+=1"
        ls_prep $dvd4
        echo "Number $count"
        let "count+=1"

        4L-cli print -q best $dvd1 "/home/ftp/$LS.bmp" && eject $dvd1 &
        4L-cli print -q best $dvd2 "/home/ftp/$LS.bmp" && eject $dvd2 &
        4L-cli print -q best $dvd3 "/home/ftp/$LS.bmp" && eject $dvd3 &
        4L-cli print -q best $dvd4 "/home/ftp/$LS.bmp" && eject $dvd4

    fi
done





Notes
  • For maximum possible happiness, run the script with Lightscribe as root. 4L-cli is unnecessarily root bound for printing.
  • Remember to "chmod 777 duplicator_script" or "chmod a+x duplicator_script" for maximum possible happiness
  • This is a multi threaded application. Remember the rule of thumb: max 2 threads per processor core... for maximum possible happiness.
Subscribe to RSS Feed Follow me on Twitter!