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:
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:
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.
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:
If you just want a script that will handle Lightscribe and nothing else:
Notes
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 |
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.










