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

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

สเปคเครื่องเก่าคือ 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

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <pre> <blockquote> <img> <h3> <h4> <h5>
  • Lines and paragraphs break automatically.
  • E-Mail addresses are hidden with reCAPTCHA Mailhide.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.