ทำเครื่องคัดลอกแผ่นซีดีแบบลูกทุ่ง

จะรีไซเคิลเครื่องเก่า มาทำเครื่องคัดลอกซีดีเพื่อถวายวัด ถ้าซื้อเครื่องคัดลอกซีดีตัวจริงใหม่ราคาประมาณหมื่นเศษ ของเราใช้รีไซเคิลเอา ราคาไม่เกินสองพันบาท (คิดเฉพาะอุปกรณ์ที่ซื้อใหม่)

สเปคเครื่องเก่าคือ Celeron 850MHz (เครื่องตรวจสอบได้ 600MHz), RAM 128MB, HD 8G (เป็น /dev/hda) ลงทุนซื้อใหม่คือ CD-Writer 3 ตัว ตัวละ 630 บาท เนื่องจากจะไม่มีจอภาพ จึงจะใช้เสียงเป็นตัวแจ้งสถานะ

จะทำให้มีการทำงานคือ

  • เมื่อเปิดเครื่อง ถาด /dev/hdb จะดีดออกเพื่อรอการอ่านข้อมูล ใช้เสียงดัง 1 ปี๊บ ทุก 3 วินาที
  • เมื่อใส่แผ่นต้นฉบับ เครื่องจะตรวจสอบแผ่น ถ้าแผ่นเสียจะแจ้งเป็นเสียง 6 ปี๊บ ทุก 3 วินาที เพื่อรออ่านแผ่นใหม่
  • ถ้าแผ่นดีจะอ่านจนเสร็จ แล้วทั้งสามถาดจะถูกดีดออกเพื่อรอการเขียนข้อมูล โดยใช้เสียงดัง 2 ปี๊บ ทุก 3 วินาที
  • จะเขียนวนไปเรื่อยจนกระทั่งปิดเครื่องเขียนด้วยถาดเปล่า ไดร์ฟนั้นก็จะหยุดทำงาน
  • เมื่อหยุดทำงานครบสามไดร์ฟแล้ว เครื่องจะปิดตัวเอง
  • ในระหว่างที่ถาดถูกดีดออก ถ้าไม่มีการใส่แผ่นใหม่เข้าไป หลังจากผ่านไป 100 ปี๊ป (หรืออาจเป็นเรากดถาดเปล่าดีดกลับเข้าไป) ถาดจะปิดตัวเอง และปิดการทำงานของถาดนั้นตลอดไป

หมายเหตุ

  • เนื่องจากเป็นการทำงานแบบขนาน ทุกไดร์ฟจึงทำงานเป็นอิสระ
  • กำหนดให้ความเร็วในการเขียนเป็นแค่ 8x เพื่อให้ฮาร์ดดิสก์อ่านข้อมูลได้ทัน และเพิ่มความคงทนของข้อมูล
  • แผ่นต้นฉบับควรเป็นแผ่นที่ดี ถึงดีมาก ผลจึงจะออกมาดี

ปรับปรุงครั้งที่ 1

  • แก้ปัญหาแผ่นธรรมดาอ่านผิดพลาด ด้วยการพยายามแยกแผ่น
    • ถ้าเป็นตระกูล VCD ซึ่งเป็น multitrack ใช้ readcd+wodim -clone
    • แต่ถ้าเป็นพวก mp3 ธรรมดา ใช้ dd+wodim แบบ normal
  • เนื่องจากทดสอบด้วย debian-desktop (etch) เลยต้องเพิ่มฟังก์ชั่นการยกเลิกการเมานต์อัตโนมัติด้วย
  • ฝากทดสอบและช่วยปรับปรุงให้ด้วยครับ

วิธีการสร้าง

เริ่มด้วยติดตั้งเดเบียน etch แบบไม่ติดตั้งอะไรเพิ่มเติมเลย

ดามด้วยเอาแพกเกจที่จำเป็นที่สคริปต์เราต้องเรียกใช้ คือ eject สำหรับดีดถาดเข้า/ออก setcd สำหรับตรวจสถานะถาด และ wodim สำหรับการคัดลอกและเขียนข้อมูล

# aptitude install eject setcd wodim

สร้างสคริปต์สำหรับให้ init เรียกใช้ตอนเปิดเครื่อง สำหรับให้อ่านแผ่นต้นฉบับ ตั้งชื่อว่า d.inittab-cpcd

# vi d.inittab-cpcd
#!/bin/bash
# THIS IS THE CD COPIER PROGRAM
# - REQUIRE PACKAGE: setcd eject wodim
# - PUT THE LINE
#     D1:2345:once:/root/d.inittab-cpcd
#   IN /etc/inittab THEN REBOOT
# - PUT THESE 2 FILES IN /root
# - RUN AS ROOT

#if [ $USER != "ROOT" ]; then
#    su
#fi

DEV=/dev/hdb        # SOURCE DRIVE
TMP=/tmp/x.bin      # TEMP IMAGE FILE
SPEED=8             # WRITE SPEED

MNT="/mnt/tmp"      # TEMP MOUNT DIR

beep() {
    echo -e "\7"
}

beeperror() {
    for i in `seq 1 6`; do beep; sleep .15; done
}

check_disk_type() {
    # RETURN 1=CLONE 2=NORMAL
    while mount | grep "$DEV "; do
        umount $DEV > /dev/null
        sleep 1;
    done
    if setcd -i $DEV | grep 'Disc found in drive: audio disc' > /dev/null
    then
        return 1
    fi
    if [ ! -d $MNT ]; then
        mkdir $MNT
    fi
    if mount | grep "$MNT "; then
        umount $MNT > /dev/null
    fi
    mount $DEV $MNT
    VAR=`ls $MNT | tr '[A-Z]' '[a-z]'`
    VAR=`echo $VAR | grep vcd | grep mpeg | grep segment | grep ext`
    while mount | grep "$DEV "; do
        umount $DEV > /dev/null
        sleep 1
    done
    if [ "$VAR" == "" ]; then
        return 2
    fi
    return 1
}

wait_read_close() {
    # MAX RETRY LOOP = 100
    for (( i=0; i<=100; i++ ))
    do
        umount $DEV
        if setcd -i $DEV | grep open > /dev/null; then
            # SLEEP 3 SECONDS
            beep; sleep 3
        else
            check_disk_type
            ISCLONE=$?
            if [ $ISCLONE -eq 1 ]; then 
                readcd -clone dev=$DEV f=$TMP
            else 
                dd if=$DEV of=$TMP
            fi
            return $ISCLONE
        fi
    done
    eject -t $1 
    /sbin/shutdown -h now
    return
}

# BEGIN MAIN
rm -rf $TMP

#CHECK 1ST CDR IS ORIGINAL CD THEN DUP. TO /tmp
while [ ! -s $TMP ]; do  
    eject $DEV
    beep
    wait_read_close $DEV
done

ISCLONE=$?

# CALL MULTIPLE INSTANCE TO DESTINATION DRIVES
#d.func.cpcd DEVICE SPEED ISOFILE
#KERNEL-2.6
/root/d.func-cpcd /dev/hdb $ISCLONE $SPEED $TMP &
/root/d.func-cpcd /dev/hdc $ISCLONE $SPEED $TMP &
/root/d.func-cpcd /dev/hdd $ISCLONE $SPEED $TMP &

wait
/sbin/shutdown -h now

อีกไฟล์นึงเป็นฟังก์ชันสำหรับเขียนซีดี ตั้งชื่อว่า d.func-cpcd

# vi d.func-cpcd
#!/bin/bash
# THIS IS THE CD COPIER PROGRAM
# - REQUIRE PACKAGE: setcd eject wodim
# - PUT THE LINE
#     D1:2345:once:/root/d.inittab-cpcd
#   IN /etc/inittab THEN REBOOT
# - PUT THESE 2 FILES IN /root
# - RUN AS ROOT

DEV=$1
ISCLONE=$2
SPEED=$3
TMP=$4

beep() {
    echo -e "\7"
}

beepwrite() {
    beep; sleep .15; beep
}

beeperror() {
    for i in `seq 1 6`; do beep; sleep .15; done
}

wait_write_close() {
    # MAX RETRY LOOP = 100
    for (( i=0; i<=100; i++ ))
    do
        # WAIT FOR INSERT DISC
        if setcd -i $DEV | grep 'is open' > /dev/null; then
            beepwrite; sleep 3
        # IF NO DISC INSERTED THEN BREAK
        elif setcd -i $DEV | grep 'No disc' > /dev/null; then
            exit 1
        else
            while mount | grep "$DEV "; do
                umount $DEV > /dev/null; sleep 1
            done
            if [ $ISCLONE -eq 1 ]; then
                wodim -clone gracetime=2 -raw96r dev=$DEV speed=$SPEED \
                    driveropts=burnfree -overburn -multi -xa1 -eject $TMP
            else
                wodim gracetime=2 dev=$DEV speed=$SPEED \
                    driveropts=burnfree -overburn -eject $TMP
            fi

            # LAST CHECK WRITING
            if setcd -i $DEV | grep 'error' > /dev/null; then
                beeperror; sleep 3
                exit 1
            else
                eject $DEV
                return
            fi
        fi
    done
    #END PROG
    eject -t $1
    exit 1
}

if [ ! $1 ] && [ ! $2 ] && [ ! $3 ] && [ ! $4 ]; then
    echo "   USAGE : $0 DRIVE ISCLONE(1=CLONE,2=NORMAL) SPEED TEMP-IMG"
    echo "   EXAM1 : $0 /dev/hdb 1 4 /tmp/x.bin"
    exit 1
fi

#CHECK IMAGE FILE
if [ ! -f $TMP ]; then
    echo "  Image file $TMP does not existed"
    exit 1
fi

#COPY TO NEW BLANK CD
while [ -f $TMP ]; do
    eject $DEV
    wait_write_close
    beepwrite
done

ต่อไปแก้ไขไฟล์ /etc/inittab ให้มาเรียกใช้โปรแกรม d.inittab-cpcd ตอนเปิดเครื่อง

# vi /etc/inittab

(ไปบรรทัดล่างสุด กด G)

...
D1:2345:once:/root/d.inittab-cpcd

เสร็จแล้วก็รีบูตทดสอบได้เลยครับ

อ้างอิง

ท่านใดเก่งเชลล์สคริปต์ฝากช่วยปรับปรุง และเผยแพร่ ด้วยนะครับ

moderator ได้ปรับ shell script นิดหน่อย เพื่อจัดหน้าและทำให้บรรทัดไม่ยาวเกินไป หากสคริปต์ไม่ทำงานอันเนื่องมาจากการจัดหน้า ก็ขอให้ถือเป็นความผิดของ moderator เอง ไม่ใช่ของคุณ wd

Creative Commons License ลิขสิทธิ์ของบทความเป็นของเจ้าของบทความแต่ละชิ้น
ผลงานนี้ ใช้สัญญาอนุญาตของครีเอทีฟคอมมอนส์แบบ แสดงที่มา-อนุญาตแบบเดียวกัน 3.0 ที่ยังไม่ได้ปรับแก้