บันทึกการทำงานเกี่ยวกับไฟล์ภาพ เสียง และวิดีโอ
ลองทำสคริปต์แปลงไฟล์ภาพเป็นวิดีโอ
วิธีใช้คือเข้าไปในไดเรคทอรี่ของไฟล์ภาพ แล้วสั่งรันโปรแกรมตรง ๆ
$ sudo aptitude install imagemagick mjpegtools
$ vi d.mkvid
#!/bin/bash #REQUIRED PACKAGE: imagemagick mjpegtools #VIDEO VARIABLE SCREEN="720x576" #DVD-PAL=720x576 DVD-NTSC=720x480 BACKGROUND="black" FRAMERATE="25" #PAL=25 NTSC=29.97 LOOP="75" #STILL IMAGE FOR 3 SEC x FRAMERATE FADEFRAME="50" #FADE FOR 2 SEC x FRAMERATE #PROGRAM VARIABLE MAINFILE="main.m2v" WORKDIR="temp" IMGSKEL="[Jj][Pp][Gg]" #-------------FUNCTION---------------- #MAKING AVI FROM JPG fMakeAvi() { echo -n "Make AVI $1 ... " jpeg2yuv -v 0 -f $FRAMERATE -j $1 -I p -n 1 -l $LOOP | yuv2lav -o $1.avi } #MAKE CROSS FADE BETWEEN AVI FRAME fMakeFade() { echo -n "Make fade $1 $2 ... " ypipe -v 0 "lav2yuv -v 0 -o -$FADEFRAME $1.avi" "lav2yuv -v 0 -f $FADEFRAME $2.avi" | transist.flt -o 0 -O 255 -d $FADEFRAME | yuv2lav -v 0 -o $1$2.avi } #MAKING M2V FROM AVI fMakeM2V() { echo -n "Make M2V $1 ... " lav2yuv -v 0 $1.avi | mpeg2enc -v 0 -o $1.m2v } #-------------BEGIN MAIN-------------- #DETERMINE FIRST FILE FIRSTJPG=`echo *$IMGSKEL | cut -d \ -f 1` #CREATE WORKING DIRECTORY if [ -d $WORKDIR ]; then echo "Directory $WORKDIR existed, exit 1" exit 1; fi mkdir $WORKDIR #MAKE JPG FILE SUITABLE FOR VIDEO BY USING imagemagick:montage for i in *$IMGSKEL; do montage -geometry $SCREEN -background $BACKGROUND -quality 100 $i $WORKDIR/$i done #CHANGE TO WORKING DIRECTORY pushd $WORKDIR #MAKE AVI FOR FIRST JPG FILE fMakeAvi $FIRSTJPG #MAKE M2V FROM FIRST AVI FILE fMakeM2V $FIRSTJPG #ADD FIRST M2V TO MAIN cat $FIRSTJPG.m2v > $MAINFILE #DELETE FIRST M2V rm $FIRSTJPG.m2v echo "" LASTFILE=$FIRSTJPG for i in *$IMGSKEL ; do if [ $i != $FIRSTJPG ] ; then #MAKE AVI FOR THIS FILE fMakeAvi $i #MAKE FADE BETWEEN LAST FILE AND THIS FILE fMakeFade $LASTFILE $i #MAKE M2V FOR THIS FILE fMakeM2V $i #MAKE M2V FOR FADE FILE fMakeM2V $LASTFILE$i #KEEP AVI OF THIS FILE #DELETE AVI OF LAST FILE rm $LASTFILE.avi #DELETE AVI OF FADE FILE rm $LASTFILE$i.avi #ADD M2V TO MAIN MPEG cat $LASTFILE$i.m2v >> $MAINFILE #ADD FADE cat $i.m2v >> $MAINFILE #ADD THIS FILE #DELETE M2V OF THIS FILE rm $i.m2v #DELETE M2V OF FADE FILE rm $LASTFILE$i.m2v #REASSIGN LAST FILE TO THIS FILE LASTFILE=$i echo "" fi ; done #DELETE AVI OF LAST FILE rm $LASTFILE.avi mv $MAINFILE .. popd #rm -rf $WORKDIR
$ chmod 755 d.mkvid
ใช้งานได้แล้ว แต่ยังมีข้อเสียอยู่คือ แปลงเป็น avi โดยไม่จำเป็น
ขอศึกษาต่ออีกหน่อยครับ
ท่านใดพอมีความรู้ ช่วยแนะนำด้วยนะครับ :)
อ้างอิง
ปรับปรุงโปรแกรมจากครั้งก่อน ลดขั้นตอนการแปลงเป็น AVI
โจทย์คือ จะแปลงภาพนิ่งจากกล้องถ่ายภาพ ไปเป็นไฟล์วิดีโอ เพื่อนำไปเขียนเป็น VCD/SVCD/DVD
$ vi d.mkvid2
#!/bin/bash #REQUIRED PACKAGE: imagemagick mjpegtools #VIDEO VARIABLE SCREEN="720x576" #DVD-PAL=720x576 DVD-NTSC=720x480 BACKGROUND="black" FRAMERATE="25" #PAL=25 NTSC=29.97 LOOP="75" #STILL IMAGE FOR 3 SEC x FRAMERATE FADEFRAME="50" #FADE FOR 2 SEC x FRAMERATE #PROGRAM VARIABLE MAINFILE="main.m2v" WORKDIR="temp" IMGSKEL="[Jj][Pp][Gg]" #-------------FUNCTION---------------- #MAKING AVI FROM JPG fMakeM2V() { echo -n "Make AVI $1 ... " jpeg2yuv -v 0 -f $FRAMERATE -j $1 -I p -n 1 -l $LOOP | mpeg2enc -v 0 -o $1.m2v } #MAKE CROSS FADE BETWEEN AVI FRAME fMakeFadeM2V() { echo -n "Make fade $1 $2 ... " ypipe -v 0 "jpeg2yuv -v 0 -f $FRAMERATE -j $1 -I p -n 1 -l $FADEFRAME" \ "jpeg2yuv -v 0 -f $FRAMERATE -j $2 -I p -n 1 -l $FADEFRAME" \ | transist.flt -o 0 -O 255 -d $FADEFRAME | mpeg2enc -v 0 -o $1$2.m2v } #-------------BEGIN MAIN-------------- #DETERMINE FIRST FILE FIRSTJPG=`echo *$IMGSKEL | cut -d \ -f 1` #CREATE WORKING DIRECTORY if [ -d $WORKDIR ]; then echo "Directory $WORKDIR existed, exit 1" exit 1; fi mkdir $WORKDIR #MAKE JPG FILE SUITABLE FOR VIDEO BY USING imagemagick:montage for i in *$IMGSKEL; do montage -geometry $SCREEN -background $BACKGROUND -quality 100 $i $WORKDIR/$i done #CHANGE TO WORKING DIRECTORY pushd $WORKDIR #MAKE M2V FROM FIRST AVI FILE fMakeM2V $FIRSTJPG #ADD FIRST M2V TO MAIN cat $FIRSTJPG.m2v > $MAINFILE #DELETE FIRST M2V rm $FIRSTJPG.m2v echo "" LASTFILE=$FIRSTJPG for i in *$IMGSKEL ; do if [ $i != $FIRSTJPG ] ; then #MAKE M2V FOR THIS FILE fMakeM2V $i #MAKE M2V FOR FADE FILE fMakeFadeM2V $LASTFILE $i #ADD M2V TO MAIN MPEG cat $LASTFILE$i.m2v >> $MAINFILE #ADD FADE cat $i.m2v >> $MAINFILE #ADD THIS FILE #DELETE M2V OF THIS FILE rm $i.m2v #DELETE M2V OF FADE FILE rm $LASTFILE$i.m2v #REASSIGN LAST FILE TO THIS FILE LASTFILE=$i echo "" fi ; done mv $MAINFILE .. popd #rm -rf $WORKDIR
$ chmod 755 d.mkvid2
ใช้งานด้วยการสร้างไดเรกทอรี่ที่บรรจุไฟล์ jpg อยู่ แล้ว cd ไปที่ไดเรกทอรี่นั้น
หลังจากนั้นก็สั่งรันโปรแกรมตรง ๆ ในไดเรกทอรี่
โปรแกรมจะสร้างไฟล์ main.m2v ออกมา เป็นไฟล์ภาพอย่างเดียว
ถ้าต้องการใส่เสียงเข้าไปด้วย
สมมุติถ้าต้นฉบับเป็น mp3
แปลง mp3 เป็น wav ด้วย mpg321
$ mpg321 sound.mp3 -w sound.wav
แปลง wav เป็น mp2 ด้วย mp2enc
$ cat sound.wav | mp2enc -v 0 -V -o main.mp2
(ถ้ามีหลายไฟล์ ใช้ cat sound1.wav sound2.wav | ...
)
นำมาเชื่อมกันเป็นไฟล์วิดีโอแบบมีเสียงด้วย mplex
$ mplex -f 8 -M main.m2v main.mp2 -o main.mpg
ตอนนี้เราสามารถเอาไฟล์ main.mpg ไปเขียนเป็น DVD ได้แล้ว
มีงานที่จะต้องเก็บแผ่นซีดี วีซีดี และดีวีดี ลงบนฮาร์ดดิสก์ เลยขอบันทึกคำสั่งที่เกี่ยวข้องเอาไว้ดูอ้างอิงในภายหลังครับ
พยายามทำเป็นแบบบรรทัดคำสั่งให้มากที่สุด เพื่อจะได้ใช้งานกับเครื่องกำลังต่ำ ๆ ได้ เผื่อจะขยายไปเป็นเครื่องเขียนซีดีอัตโนมัติ
เครื่องมือที่ใช้ พยายามใช้ cdrecord (wodim) ให้มากที่สุด เพราะเข้าใจว่าเขียนได้เรียบร้อยกว่า cdrdao
ติดตั้งด้วยคำสั่ง
$ sudo aptitude install cdrecord cdrdao
$ dd if=/dev/cdrom of=XXX.iso
$ cdrecord speed=8 dev=/dev/cdrom -data XXX.iso
$ sudo mount -t iso9660 XXX.iso /mnt/disk
$ mkisofs -r -o XXX.iso /PATH/TO/BACKUP
$ mkisofs -r -J -l -d -allow-multidot -allow-leading-dots -no-bak -o XXX.iso /PATH/TO/BACKUP/
$ cdrecord speed=8 dev=/dev/cdrom -data XXX.iso
$ readcd -clone dev=/dev/cdrom f=XXX.bin
$ cdrecord -clone gracetime=2 -raw96r dev=/dev/cdrom speed=8 driveropts=burnfree -overburn -multi -xa1 -eject XXX.bin
$ mplayer XXX.bin
$ sudo aptitude install module-assistant
$ sudo m-a a-i cdfs
$ sudo modprobe cdfs
$ sudo mount -t cdfs -r /dev/cdrom /mnt/disk
$ sudo aptitude install vcdtools
$ mkvcdfs /home/user1/mpg/*
$ cdrdao write --device /dev/cdrom vcd.toc
ตอนนี้วิธีที่ง่ายและดีที่สุดคือ ซื้อโปรแกรม nerolinux มาใช้
แต่ถ้าหากจะต้องการใช้โอเพนซอร์สล้วน ๆ และต้องการเป็นแบบบรรทัดคำสั่ง มีรายละเอียดดังนี้
$ dd bs=1k if=XXX.nrg of=XXX.iso skip=300
$ sudo aptitude install nrg2iso
$ nrg2iso XXX.nrg xxx.iso
$ sudo mount -t iso9660 -o loop,offset=307200 XXX.nrg /mnt/disk
$ sudo aptitude install fuseiso
$ sudo fuseiso XXX.nrg /mnt/disk
$ cd
$ wget http://www.vcdgear.com/files/vcdgear176-040415_linux.tar.gz
$ tar xfz vcdgear176-040415_linux.tar.gz
$ ~/vcdgear/vcdgear -nrg2mpg XXX.nrg
$ mplayer XXX.nrg
หมายเหตุ
โพสต์นี้ยังไม่เสร็จ ยังขาดรายละเอียดของออปชั่นในบรรทัดคำสั่งอีกมาก และจะพยายามเติมงานของดีวีดีลงไปด้วย
ดังนั้น จะต้องมีการเปลี่ยนแปลงเรื่อย ๆ ครับ
อ้างอิง
ต้องการเขียนแผ่นข้อมูล ซึ่งเป็นไฟล์ mp3 ธรรมดา
ที่แรกเขียนด้วย k3b ปรากฎว่าอ่านด้วยคอมพิวเตอร์ออกสบาย ๆ แต่กลับอ่านด้วยเครื่องเล่นดีวีดีทั่วไปตามท้องตลาดไม่ได้ ไม่ว่าลองเปลี่ยนค่าเป็น DAO TAO Mode1 Mode2 ยังไงก็อ่านไม่ออก
ไม่แน่ใจเครื่องเขียนว่าเก่าไปหรือเปล่า
เลยลองดาวน์โหลด Nero Linux 3 มาลองเขียนดู ปรากฎว่าอ่านได้สบาย ๆ
ลองเขียนด้วยโปรแกรมปริยายของ Gnome คือ nautilus-cd-burner ก็อ่านออกเหมือนกัน
เลยไม่ทราบว่าตั้งค่า k3b ผิดตรงไหน คงต้องกลับไปศึกษาต่อ เที่ยวนี้บันทึกไว้แค่นี้ก่อน
ลองบนเดเบียน sid ครับ
มีงานต้องตัดต่อวีดีโอจากกล้องวีดีโอแบบเขียนลงแผ่น ดังนั้นไฟล์ที่ได้จะมีโครงสร้างเป็นดีวีดีแล้ว แต่เราต้องการนำมาตัดต่อและเชื่อมกัน เพื่อนำไปเขียนลงดีวีดีแผ่นใหม่
เริ่มด้วยติดตั้งแพกเกจ
$ sudo aptitude install kino ffmpeg mplayer dvd+rw-tools mjpegtools mkisofs dvdauthor normalize-audio audacity k3b
ตัดต่อด้วย kino
$ kino /media/cdrom0/DVD_RTAV/VR_MOVIE.VRO
เมื่อตัดต่อเรียบร้อยสามารถส่งออกเป็นไฟล์ mpeg
Export -> MPEG -> vid01.mpeg
เลือก Deinterlace ตามชอบ
ทำโครงสร้าง DVD
$ mkdir ./dvd
$ dvdauthor -t -o ./dvd vid*.mpeg
$ dvdauthor -o ./dvd -T
ทำเป็น iso
$ mkisofs -dvd-video -o dvd.iso ./dvd
เขียนลงแผ่น
$ growisofs -dvd-compat -speed=1 -Z /dev/hdb=dvd.iso
เสร็จแล้ว
การบันทึกเสียงจากวีดีโอเป็น mp3
เมื่อผ่านขั้นตอนตัดต่อจาก kino แล้ว อาจส่งออกไฟล์เสียงออกมาเป็น wav ได้เลย
Export -> Audio -> audio.wav
หรือถ้าส่งออกมาเป็นไฟล์ mpeg แล้วก็สามารถใช้ ffmpeg ได้ด้วยคำสั่ง
$ ffmpeg -i video.mpeg audio.wav
เกลี่ยเสียงให้ดังพอดี
$ normalize-audio audio.wav
ปรับระดับ Equalize ด้วย audacity
$ audacity audio.wav
ผมเลือกใช้
Effect -> Equalization... -> EMI 78
และส่งออกมาเป็น wav หรือ mp3 ตามต้องการ
หากส่งออกเป็น wav สามารถแปลงเป็น mp3 โดย lame
$ lame -h audio.wav audio.mp3
อ้างอิง
เอามาจาก Photoshop-ish Keyboard Shortcuts for The Gimp 2.2
เพิ่งรู้ว่า gimp สามารถสร้างคีย์ลัดเองได้ โดยผ่านไฟล์ menurc
ซึ่งอยู่ภายในไดเรคทอรี่ ~/gimp-2.2 ( ของวินโดวส์จะเป็น C:\Documents and Settings\<user name>\.gimp-2.2 )
วิธีการก็คือไปเอาไฟล์ ps-menurc ที่เขาสร้างไว้เลียนแบบคีย์ลัดของ Photoshop (ตามลิงค์)
เปลี่ยนชื่อเป็น menurc แล้วใส่เข้าในไดเรคทอรี่ของ gimp
เพียงเท่านี้ ชีวิตภายใต้ร่มเงา gimp ก็สบายขึ้นเยอะ :)
$ cd ~/.gimp-2.2
$ mv menurc menurc.old
$ wget http://epierce.freeshell.org/gimp/ps-menurc
$ mv ps-menurc menurc
$ cd
ถ้าจะสร้างคีย์ลัดไว้ใช้เอง ก็แก้เองในไฟล์นี้แหละครับ โครงสร้างไฟล์เป็นแบบง่าย ๆ
การกำจัด Noise ของไฟล์ภาพ จำได้ว่าฝั่งวินโดวส์ มีโปรแกรมที่มีชื่อเสียงอยู่สองตัวคือ
Neat Image ที่มาก่อน และ Noise Ninja ที่ดูเหมือนจะมาทีหลังแต่ดังกว่า
ฝั่งลินุกส์ยังไม่ทราบว่ามีตัวไหน ผมลองค้นกูเกิลดู ไปพบที่เว็บนี้
Nikon D70 under Linux
ซึ่งท่านผู้เขียน พยายามเลือกใช้ลินุกส์กับงานด้านภาพถ่ายทั้งหมด ท่านจึงเขียนสคริปต์ไพธอนขึ้นมาใช้เองสำหรับการกำจัด Noise โดยทำเป็นปลั๊กอินใน Gimp
ผมลองทดสอบดูพบว่า ภาพที่ผ่านการโปรเซสแล้ว ยังคงรายละเอียดไว้ได้ดี ไม่ดูเป็นพลาสติก หรือขาดความเป็นธรรมชาติ มีเพี้ยนสีเล็กน้อย ซึ่งสามารถแก้โดยดึง curve ขึ้นมาได้ง่าย ๆ
จึงขออนุญาตบันทึกการติดตั้งไว้เล็กน้อยครับ
ทดลองบนเดเบียน sid
เริ่มด้วยติดตั้งแพกเกจที่จำเป็น
$ sudo aptitude update
$ sudo aptitude install gimp-python python-numarray
ดาวน์โหลดแพกเกจ และนำไปใส่ไว้ในไดเรกทอรี่ปลั๊กอินของ Gimp
$ wget http://pages.quicksilver.net.nz/pepe/d70/noise_remover.py
$ sudo mv noise_remover.py /usr/lib/gimp/2.0/plug-ins/
เสร็จแล้ว เรียกใช้งานด้วยเมนู Plugins -> Noise -> Remove
ปรกติ gimp ทำภาพ gif แบบโปร่งใสได้จำกัด คือไม่สามารถไล่ระดับความโปร่งใสแบบเดียวกับ png ทำได้
วิธีแก้คือให้สร้างภาพเป็น png เมื่อทำจนเสร็จเรียบร้อย ก็แค่ใช้เชลล์เปลี่ยนนามสกุลจาก png เป็น gif ก็จะได้ภาพโปร่งใสตามต้องการ
หมายเหตุ
update
จะรีไซเคิลเครื่องเก่า มาทำเครื่องคัดลอกซีดีเพื่อถวายวัด
เครื่องใหม่ราคาประมาณหมื่นเศษ
สเปคเครื่องเก่าคือ Celeron 850MHz, RAM 128MB, HD 15G (เป็น /dev/hda)
ลงทุนซื้อใหม่คือ CD-Writer 3 ตัว ตัวละ 750 บาท
เนื่องจากจะไม่มีจอภาพ จึงจะใช้เสียงเป็นตัวแจ้งสถานะ
จะทำให้มีการทำงานคือ
หมายเหตุ
วิธีการสร้าง
เริ่มด้วย ติดตั้งอูบุนตู dapper แบบ server โดยเลือกไม่ติดตั้งอะไรเพิ่มเติมเลย
ดามด้วยเอาแพคเก็จที่จำเป็นคือ setcd สำหรับเขียนสคริปต์ และ cdrecord
$ su
# aptitude install eject setcd cdrecord
สร้างสคริปต์สำหรับให้ init เรียกใช้ตอนเปิดเครื่อง สำหรับให้อ่านแผ่นต้นฉบับ
ตั้งชื่อว่า d.inittab-cpcd
# vi d.inittab-cpcd
#!/bin/bash # THIS IS THE COPY CD PROGRAM # PUT THE LINE # D1:2345:once:/root/d.inittab-cpcd # IN /etc/inittab THEN REBOOT # beep() { echo -e "\7" } beeperror() { for i in `seq 1 6`; do beep; sleep .15; done } wait_read_close() { # MAX RETRY LOOP = 100 for (( i=0; i<=100; i++ )) do if setcd -i $DEV | grep open >> /dev/null; then # SLEEP 1 SECONDS beep; sleep 3 else readcd -clone dev=$DEV f=$TMP return fi done eject -t $1 /sbin/shutdown -h now return } # TEMPOLARY IMAGE FILE DEV=/dev/hdb #KERNEL-2.4 #ATA="ATAPI:0,1,0" #KERNEL-2.6 #ATA=/dev/hdb ATA=/dev/hdb TMP=/tmp/x.bin rm -rf $TMP #CHECK 1ST CDR IS ORIGINAL CD THEN DUP. TO /tmp while ! [ -s $TMP ] do eject $DEV wait_read_close $DEV beep done # CALL MULTIPLE INSTANCE #d.func.cpcd DEVICE SPEED ISOFILE #KERNEL-2.4 #/root/sh-func-cpcd /dev/hdb ATAPI:0,1,0 8 $TMP & #/root/sh-func-cpcd /dev/hdc ATAPI:1,0,0 8 $TMP & #/root/sh-func-cpcd /dev/hdd ATAPI:1,1,0 8 $TMP & #KERNEL-2.6 /root/d.func-cpcd /dev/hdb /dev/hdb 8 $TMP & /root/d.func-cpcd /dev/hdc /dev/hdc 8 $TMP & /root/d.func-cpcd /dev/hdd /dev/hdd 8 $TMP & wait /sbin/shutdown -h now
อีกไฟล์นึงเป็นฟังก์ชั่นสำหรับเขียนซีดี ตั้งชื่อว่า d.func-cpcd
# vi d.func-cpcd
#!/bin/bash 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 cdrecord -clone -raw96r dev=$ATA speed=$SPEED driveropts=burnfree gracetime=2 -overburn -eject $TMP # LAST CHECK WRITING if setcd -i $DEV | grep 'error' >> /dev/null; then beeperror; sleep 3 else eject $DEV return fi fi done #END PROG eject -t $1 exit 1 } if [ ! $1 ] && [ ! $2 ] && [ ! $3 ] && [ ! $4 ] ; then echo " USAGE : $0 DRIVE ATAPI SPEED TEMP-IMG" echo " EXAM1 : $0 /dev/hdb ATAPI:0,1,0 4 /tmp/x.bin" exit 1 fi DEV=$1 ATA=$2 SPEED=$3 TMP=$4 #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 $DEV beepwrite done
ต่อไปแก้ไขไฟล์ /etc/inittab ให้มาเรียกใช้โปรแกรม d.inittab-cpcd ตอนเปิดเครื่อง
# vi /etc/inittab
(ไปบรรทัดล่างสุด กด G)
... D1:2345:once:/root/d.inittab-cpcd
เสร็จแล้วก็รีบูตทดสอบได้เลยครับ
update: 49-11-25
cdrecord เติมพารามิเตอร์ gracetime=2
update: ubuntu edgy
edgy ใช้แพกเกจ upstart แทน sysvinit ทำให้บูตเร็วขึ้น
upstart ไม่ใช้ไฟล์ /etc/inittab แต่ใช้สคริปต์ใน /etc/event.d แทน
เราต้องสร้างสคริปต์ สมมุติว่าชื่อ cpcd เอาไว้ใน /etc/event.d
(สคริปต์นี้ ห้ามรันได้ คือแอตทริบิวต์ x ต้องไม่ถูกเซ็ต)
$ sudo vi /etc/event.d/cpcd
# start on runlevel-2 start on runlevel-3 start on runlevel-4 start on runlevel-5 # stop on shutdown # exec /root/d.inittab-cpcd console output
รีบูตเครื่องก็ใช้ได้
update: 49-11-28
มีปัญหากับไดร์ฟ
ไม่สามารถอ่านดิสก์แบบ multisession ที่ถูก overburn ได้ (เช่นแผ่น VCD)
ยังแก้ไม่ตก
เห็นคำถามเกี่ยวกับการแบ่งไฟล์สื่อออกเป็นหลายส่วนที่ ubuntuclub.com
ด้วยต้องการคลายเครียด จึงวางแผนลงมือเขียนสคริปต์ โดยคิดให้สคริปต์มีการทำงานดังต่อไปนี้
ffmpeg -i "$INFILE" 2>&1 | grep "Duration" | cut -d ' ' -f 4 | sed s/,//
เสร็จแล้วเขียนออกมาหยาบ ๆ และทดสอบไปเล็กน้อยว่าใช้งานได้จริงแล้วเลยเอามาบันทึกไว้กันลืมเสียหน่อย
โดยผลลัพธ์ที่ได้ออกมาเป็นสคริปต์ sep_media.sh เป็นดังนี้:
sep_media.sh:
#!/bin/bash # # Script for separate media file by MENCoder # by Thanomsub Noppaburana <donga.nb@gmail.com> # Usage: sep_media.sh # Example: # For separate Doraemon.avi into 20 parts with prefix "Doraemon_Part" # sep_media.sh Doraemon.avi Doraemon_Part 20 # INFILE="$1" OUTFILEPREFIX="$2" TOTALPART="$3" EXTENSION="" [ ! -z "$INFILE" ] && EXTENSION="`echo "$INFILE" | awk -F . '{print $NF}'`" ## ----------------------------------------------------------------- ## ## functions declaration ## ----------------------------------------------------------------- ## usage() { echo echo -e "Usage:" echo -e "\t`basename $0` " echo -e "Example:" echo -e "\tFor separate Doraemon.avi into 20 parts with prefix \"Doraemon_Part\"" echo -e "\tsep_media.sh Doraemon.avi Doraemon_Part 20" echo } getTotalLength() { echo `ffmpeg -i "$INFILE" 2>&1 | grep "Duration" | cut -d ' ' -f 4 | sed s/,// | awk -F: '{ print ($1*3600)+($2*60)+$3 }'` } getEachPartLength() { echo $1:$2 | awk -F: '{ print $1/$2 }' } separateMedia() { TOTALPART=$1 TOTALLENGTH=$2 EACHPARTLENGTH=$3 for ((i=0;i<$TOTALPART;i++)) do STARTPOS=`echo $i $EACHPARTLENGTH | awk '{print ($1*$2)+0.01}'` echo "=====================================================================================================" echo " Separating media part $i: $OUTFILEPREFIX$i.$EXTENSION : " echo "-----------------------------------------------------------------------------------------------------" mencoder -of lavf -oac copy -ovc copy -o $OUTFILEPREFIX$i.$EXTENSION -ss $STARTPOS -endpos $EACHPARTLENGTH $INFILE echo "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" done } ## ----------------------------------------------------------------- ## ## main program ## ----------------------------------------------------------------- ## if [ -z "$INFILE" -o -z "$OUTFILEPREFIX" -o -z "$TOTALPART" ]; then usage exit 0 fi TOTALLENGTH=`getTotalLength` EACHPARTLENGTH=`getEachPartLength $TOTALLENGTH $TOTALPART` separateMedia $TOTALPART $TOTALLENGTH $EACHPARTLENGTH
ตัวอย่างเช่น ต้องการแยก Doraemon.avi เป็น 20 ส่วน โดยให้ไฟล์ที่โดนแยกนำหน้าด้วยชื่อ "Doraemon_Part"
sep_media.sh Doraemon.avi Doraemon_Part 20
ซึ่งก็จะได้ผลลัพธ์เป็นแฟ้ม Doraemon_Part0.avi ถึง Doraemon_Part19.avi ออกมา เป็นต้น
ผู้สนใจสามารถดาวน์โหลดไปใช้ได้เลยครับ ดาวน์โหลดสคริปต์ sep_media.sh
จากนั้นเซฟไว้ใน search path และอย่าลืมตั้ง permission ให้ประมวลผลได้ก่อน ด้วยคำสั่ง
sudo chmod ugo+x /path/to/sep_media.sh
เป็นอันพร้อมใช้งานครับ ^_^
โจทย์คือแปลงไฟล์วีดีโอจากแผ่นดีวีดี Double Layer 8.5G มาเป็นแผ่นดีวีดีธรรมดา 4.7G โดยให้คุณภาพภาพและเสียงคงเดิม
วิธีการคือจะคัดลอกไฟล์ vob มาตัดต่อแล้วเขียนกลับลงไปบนแผ่น 4.7G
ต้องการเครื่องมือคือ ffmpeg dvdauthor mkisofs (genisoimage) และ vlc เพื่อตรวจดูภาพ และ wodim เพื่อเขียนแผ่น
โดยเฉพาะ ffmpeg ต้องการตัวที่มาจาก debian-multimedia.org เพราะมีไลบรารีมากกว่าของ debian เอง
$ sudo vi /etc/apt/sourcelist
... deb http://www.debian-multimedia.org squeeze main ...
$ sudo aptitude update $ sudo aptitude install ffmpeg dvdauthor mkisofs vlc wodim
เตรียมไดเรคทอรี่ temp ไว้เก็บไฟล์ vob ชั่วคราว และ dvd ไว้เก็บโครงสร้างไฟล์สำหรับเขียนลงแผ่น
$ mkdir temp dvd
คัดลอกไฟล์ vob จากแผ่นด้วยคำสั่ง dvdunauthor
$ cd temp $ dvdunauthor /media/cdrom0
จะได้ไฟล์ vob ออกมาหลายไฟล์ แต่เราจะเก็บเฉพาะไฟล์ vob_01t_xxx.vob เท่านั้น
$ rm vob_01m*
ตรวจดูขนาดไฟล์ว่ารวมกันมากกว่า 4.3G หรือไม่ หากมากกว่าให้ลองดูภาพด้วย vlc แล้วสังเกตุช่วงเวลาที่จะทำการตัดต่อไว้
สมมุติเราได้ไฟล์ vob_01t_001.vob ออกมาไฟล์เดียว และจะตัดที่เวลา 1 ชั่วโมง 2 นาที 3 วินาที ใช้คำสั่ง ffmpeg ในการตัด
$ ffmpeg -i vob_01t_001.vob -sameq -target dvd -ss 0:0:0 -t 01:02:03 file1.vob
จะได้ file1.vob เป็นไฟล์ส่วนแรก
และ
$ ffmpeg -i vob_01t_001.vob -sameq -target dvd -ss 01:02:03 file2.vob
จะได้ file2.vob เป็นไฟล์ส่วนหลัง
เตรียมนำไฟล์ที่ได้ไปสร้างเป็นโครงสร้าง dvd คือ
สร้างไฟล์โครงสร้าง xml สมมุติชื่อ auth.xml บรรจุไฟล์ file1.vob ลงไป
$ vi auth.xml
<dvdauthor allgprm="yes"> <vmgm /> <titleset> <titles> <pgc> <vob file="file1.vob" /> </pgc> </titles> </titleset> </dvdauthor>
สร้าง dvd
$ dvdauthor -o ../dvd -x auth.xml
สร้างไฟล์ iso
$ mkisofs -dvd-video -o ../dvd.iso ../dvd
นำไปเขียนแผ่น
$ wodim -v gracetime=2 dev=/dev/cdrom speed=1 -eject ../dvd.iso
ต่อจากนี้ก็เอาไฟล์ที่เหลือ คือ file2.vob มาสร้างเป็นแผ่นต่อไป
เสร็จแล้วครับ
มีงานต้องแปลงไฟล์เสียงสกุล amr ไปเป็น mp3 เพื่อแจกจ่าย พบปัญหาว่า
ทางแก้ไขคือ
-q9
โปรแกรมที่ต้องการใช้งานคือ ffmpeg, normalize-audio, lame จาก debian-multimedia.org
(ผมใช้ squeeze ให้เปลี่ยนตามที่ใช้จริง)
$ sudo vi /etc/apt/sources.list
... deb http://www.debian-multimedia.org squeeze main non-free ...
$ sudo apttiude update
$ sudo aptitude install ffmpeg normalize-audio lame
คำสั่งที่ใช้คือ
$ for i in *amr; do ffmpeg -i "$i" /tmp/x.wav normalize-audio /tmp/x.wav lame -q9 /tmp/x.wav /PATH/TO/NEW/FILE/${i%amr}mp3" rm /tmp/x.wav done
จะได้ไฟล์ mp3 ที่คุณภาพและขนาดไฟล์ใกล้เคียงกับต้นฉบับ amr และไม่มีเสียง hiss ตามต้องการ
ต้องการอัดเสียงด้วยบรรทัดคำสั่งบนเครื่องเซิร์ฟเวอร์ที่ไม่ได้ลง X ไว้
หากต้องการปรับความดังของไมค์ หรือปรับตั้งลำโพง ต้องติดตั้ง alsamixer ก่อน
$ sudo aptitude install alsa-utils
$ alsamixer
ปรับตั้งให้เรียบร้อย
ติดตั้งโปรแกรมอัดเสียง
$ sudo aptitude install sound-recorder
สมมุติจะอัดเทป 1 หน้า 30 นาที
$ sound-recorder -c 2 -b 16 -P -S 30:00 recording.wav
-c 2
คือสเตริโอ 2 ช่อง
-b 16
คือสุ่มด้วยอัตรา 16 บิต
-P
คือให้โปรแกรมมี priority เยอะกว่าโปรแกรมอื่น
-S 30:00
คืออัดด้วยเวลา 30 นาที
เสร็จแล้ว
เอามาจาก
แผ่นดีวีดีข้อมูลเป็นรอยมาก (อาจไม่ค่อยคอมแพตด้วย เป็นแผ่น DVD+R)
คัดลอกด้วย Nautilus ทีละหลาย ๆ ไฟล์ไม่ได้
ใช้แบบบรรทัดคำสั่งก็ไม่ด้
ผ่านด้วยการคัดลอกทีละไฟล์
จะรีไซเคิลเครื่องเก่า มาทำเครื่องคัดลอกซีดีเพื่อถวายวัด
ถ้าซื้อเครื่องคัดลอกซีดีตัวจริงใหม่ราคาประมาณหมื่นเศษ
ของเราใช้รีไซเคิลเอา ราคาไม่เกินสองพันบาท (คิดเฉพาะอุปกรณ์ที่ซื้อใหม่)
สเปคเครื่องเก่าคือ Celeron 850MHz (เครื่องตรวจสอบได้ 600MHz), RAM 128MB, HD 8G (เป็น /dev/hda)
ลงทุนซื้อใหม่คือ CD-Writer 3 ตัว ตัวละ 630 บาท
เนื่องจากจะไม่มีจอภาพ จึงจะใช้เสียงเป็นตัวแจ้งสถานะ
จะทำให้มีการทำงานคือ
หมายเหตุ
วิธีการสร้าง
เริ่มด้วยติดตั้งเดเบียน etch แบบไม่ติดตั้งอะไรเพิ่มเติมเลย
(ผมใช้แผ่น sarge แล้วอัปเกรดเป็น etch เลือกใช้เคอร์เนล 2.6.18-3-686)
ดามด้วยเอาแพกเกจที่จำเป็นที่สคริปต์เราต้องเรียกใช้ คือ
eject สำหรับดีดถาดเข้า/ออก setcd สำหรับตรวจสถานะถาด และ cdrecord สำหรับการคัดลอกและเขียนข้อมูล
$ su
# aptitude install eject setcd cdrecord
หมายเหตุ สำหรับแพกเกจ cdrecord นั้น เป็นแพกเกจเสมือน ซึ่งจะไปติดตั้งแพกเกจจริงชื่อ wodim อีกทีนึง
ช่วงก่อนหน้านี้ แพกเกจ wodim มีความสามารถน้อยกว่า cdrecord ตัวจริงมาก bug ก็เยอะมาก
แต่ตอน etch ใกล้จะออกนี้ แพกเกจนี้มีความสามารถทัดเทียมแพกเกจจริงแล้ว สามารถนำมาใช้งานได้จริงเลยครับ
สร้างสคริปต์สำหรับให้ init เรียกใช้ตอนเปิดเครื่อง สำหรับให้อ่านแผ่นต้นฉบับ
ตั้งชื่อว่า d.inittab-cpcd
# vi d.inittab-cpcd
#!/bin/bash # THIS IS THE COPY CD PROGRAM # PUT THE LINE # D1:2345:once:/root/d.inittab-cpcd # IN /etc/inittab THEN REBOOT # beep() { echo -e "\a" } beeperror() { for i in `seq 1 6`; do beep; sleep .15; done } wait_read_close() { # MAX RETRY LOOP = 100 for (( i=0; i<=100; i++ )) do if setcd -i $DEV | grep open >> /dev/null; then # SLEEP 1 SECONDS beep; sleep 3 else readcd -clone dev=$DEV f=$TMP return fi done eject -t $1 /sbin/shutdown -h now return } # TEMPOLARY IMAGE FILE DEV=/dev/hdb #KERNEL-2.4 #ATA="ATAPI:0,1,0" #KERNEL-2.6 #ATA=/dev/hdb ATA=/dev/hdb TMP=/tmp/x.bin rm -rf $TMP #CHECK 1ST CDR IS ORIGINAL CD THEN DUP. TO /tmp while ! [ -s $TMP ] do eject $DEV wait_read_close $DEV beep done # CALL MULTIPLE INSTANCE #d.func.cpcd DEVICE SPEED ISOFILE #KERNEL-2.4 #/root/sh-func-cpcd /dev/hdb ATAPI:0,1,0 8 $TMP & #/root/sh-func-cpcd /dev/hdc ATAPI:1,0,0 8 $TMP & #/root/sh-func-cpcd /dev/hdd ATAPI:1,1,0 8 $TMP & #KERNEL-2.6 /root/d.func-cpcd /dev/hdb /dev/hdb 8 $TMP & /root/d.func-cpcd /dev/hdc /dev/hdc 8 $TMP & /root/d.func-cpcd /dev/hdd /dev/hdd 8 $TMP & wait /sbin/shutdown -h now
อีกไฟล์นึงเป็นฟังก์ชั่นสำหรับเขียนซีดี ตั้งชื่อว่า d.func-cpcd
# vi d.func-cpcd
#!/bin/bash beep() { echo -e "\a" } 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 cdrecord -clone -raw96r dev=$ATA speed=$SPEED driveropts=burnfree gracetime=2 -overburn -eject $TMP # LAST CHECK WRITING if setcd -i $DEV | grep 'error' >> /dev/null; then beeperror; sleep 3 else eject $DEV return fi fi done #END PROG eject -t $1 exit 1 } if [ ! $1 ] && [ ! $2 ] && [ ! $3 ] && [ ! $4 ] ; then echo " USAGE : $0 DRIVE ATAPI SPEED TEMP-IMG" echo " EXAM1 : $0 /dev/hdb ATAPI:0,1,0 4 /tmp/x.bin" exit 1 fi DEV=$1 ATA=$2 SPEED=$3 TMP=$4 #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 $DEV beepwrite done
ต่อไปแก้ไขไฟล์ /etc/inittab ให้มาเรียกใช้โปรแกรม d.inittab-cpcd ตอนเปิดเครื่อง
# vi /etc/inittab
(ไปบรรทัดล่างสุด กด G)
... D1:2345:once:/root/d.inittab-cpcd
เสร็จแล้วก็รีบูตทดสอบได้เลยครับ
อ้างอิง
ท่านใดเก่งเชลล์สคริปต์ฝากช่วยปรับปรุง และเผยแพร่ ด้วยนะครับ
จะรีไซเคิลเครื่องเก่า มาทำเครื่องคัดลอกซีดีเพื่อถวายวัด
สเปคเครื่องเก่าคือ AMD Sempron(tm) 2000+, RAM 512MB, HD 40G (เป็น /dev/sda)
ลงทุนซื้อใหม่คือ CD-Writer 4 ตัว ตัวละ 545 บาท (IDE 3 และ SATA 1)
เนื่องจากจะไม่มีจอภาพ จึงจะใช้เสียงเป็นตัวแจ้งสถานะ
จะทำให้มีการทำงานคือ
เริ่มด้วยติดตั้งเดเบียน squeeze แบบไม่ติดตั้งอะไรเพิ่มเติมเลย
ดามด้วยเอาแพกเกจที่จำเป็นที่สคริปต์เราต้องเรียกใช้ คือ
# aptitude install eject setcd cdrdao
สร้างสคริปต์สำหรับให้ rc.local เรียกใช้ตอนเปิดเครื่อง สำหรับให้อ่านแผ่นต้นฉบับ
ตั้งชื่อว่า d.rc-cpcd
# vi /usr/local/sbin/d.rc-cpcd
#!/bin/bash # CD COPIER PROGRAM # PREREQUISITE: # # aptitude install eject cdrdao setcd dvd+rw-tools # file: d.rc-cpcd d.func-cpcd # PUT d.rc-cpcd AND d.func-cpcd IN /usr/local/sbin # THEN CALL d.rc-cpcd FROM /etc/rc.local #VARIABLE SRC=/dev/sr0 #SOURCE DRIVE TOC=/tmp/toc.bin #TEMP.IMAGE FILE DSC=" /dev/sr0 /dev/sr1 /dev/sr2 /dev/sr3 " #DESTINATION DRIVE . /usr/local/sbin/d.common-func wait_read_close() { # MAX RETRY LOOP = 100 for (( i=0; i<=100; i++ )); do if setcd -i $SRC | grep 'CD tray is open' >> /dev/null; then # SLEEP 1 SECONDS beep_close elif setcd -i $SRC | grep 'Drive is not ready' >> /dev/null; then sleep 1 else if setcd -i $SRC | grep 'No disc is inserted' >> /dev/null; then break else #DO READ cdrdao read-cd --device $SRC --read-raw --datafile /tmp/data.bin $TOC return fi fi done eject -t $SRC /sbin/shutdown -h now return } rm -rf $TOC #CHECK 1ST CDR IS ORIGINAL CD THEN DUP. TO /tmp while ! [ -s $TOC ]; do eject $SRC echo "eject $SRC" wait_read_close $SRC beep done # CALL MULTIPLE INSTANCE IN $DSC DRIVES for i in $DSC; do if [ "$i" ]; then /usr/local/sbin/d.func-cpcd $i $TOC & fi done wait /sbin/shutdown -h now
อีกไฟล์นึงเป็นฟังก์ชั่นสำหรับเขียนซีดี ตั้งชื่อว่า d.func-cpcd
# vi /usr/local/sbin/d.func-cpcd
#!/bin/bash DEV=$1 TOC=$2 SPEED=1 . /usr/local/sbin/d.common-func 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 beep_write; sleep 3 elif setcd -i $DEV | grep 'Drive is not ready' >> /dev/null; then sleep 1 elif setcd -i $DEV | grep 'No disc' >> /dev/null; then # IF NO DISC INSERTED THEN BREAK exit 1 else # DO WRITE cdrdao write --device $DEV --speed $SPEED --overburn -n $TOC # LAST CHECK WRITING if setcd -i $DEV | grep 'error' >> /dev/null; then beep_error; sleep 3 eject $DEV else eject $DEV return fi fi done #END PROG eject -t $DEV exit 1 } if [ ! $1 ] && [ ! $2 ] ; then echo " USAGE : $0 DRIVE SPEED TEMP-IMG" echo " EXAM1 : $0 /dev/sr0 /tmp/toc.bin" exit 1 fi #CHECK IMAGE FILE if ! [ -f $TOC ] ; then echo " Image file $TOC does not existed" exit 1 fi #COPY TO NEW BLANK CD while [ -f $TOC ]; do eject $DEV wait_write_close beep_write done
และสุดท้ายคือไฟล์ฟังก์ชั่นที่ใช้ร่วมกัน
# vi /usr/local/sbin/d.common-func
#!/bin/bash beep() { echo -e "\a" } beep_close() { beep; sleep 1; } beep_write() { beep; sleep .15; beep } beep_error() { for i in `seq 1 6`; do beep; sleep .15; done }
ต่อไปแก้ไขไฟล์ /etc/rc.local ให้มาเรียกใช้โปรแกรม d.rc-cpcd ตอนเปิดเครื่อง
# vi /etc/rc.local
... /usr/local/sbin/d.rc-cpcd exit 0
เสร็จแล้วรีบูตทดสอบได้เลย
ปรับปรุงจาก debian: เครื่องคัดลอกแผ่นซีดี
ทำบนเดเบียน Lenny โดยจะปรับให้สามารถเขียนแผ่น DVD ได้ด้วย
มีการเปลี่ยนแปลงสคริปต์เล็กน้อย แต่คราวนี้ขอเขียนขั้นตอนแบบเริ่มใหม่ตั้งแต่ต้น
สมบัติของเครื่องที่นำมาใช้ทดสอบและรุ่นของเดเบียน
cpu: AMD Athlon (tm) XP 2400+
motherboard: ECS L7VMM2
ram: DDR 512M
harddisk: Seagate 10G เป็น /dev/hda
cdrom: DVD-Writer Lite-on จำนวน 3 เครื่อง เป็น /dev/hdb /dev/hdc และ /dev/hdd ตามลำดับ
os: Debian GNU/Linux 5.0 (2.6.26-2-686) - Lenny
packages: wodim setcd dvd+rw-tools
ความสามารถของโปรแกรม
สามารถคัดลอก cd, vcd และ dvd ได้ เป็นแบบเข้า 1 ออก 3 และเขียนด้วยความเร็วต่ำสุดที่เป็นไปได้ ทั้งนี้เพื่อให้แผ่นมีความทนทานใช้งานได้ยาวนาน
การทำงานของเครื่อง
เริ่มสร้างด้วย...
การติดตั้งเดเบียนแบบเปล่า ๆ ดูตัวอย่างจาก debianclub: การติดตั้ง Debian เป็น Desktop แต่ของเราไม่ต้องเลือก Desktop Environment
ติดตั้งแพกเกจที่ต้องการ
# aptitude install vim less wodim dvd+rw-tools setcd
สร้างไฟล์เริ่มการทำงานอ่านซีดี ชื่อ d.inittab-cpcd
# vi /root/d.inittab-cpcd
#!/bin/bash # CD COPIER PROGRAM # PREREQUISITE: # # aptitude install wodim setcd dvd+rw-tools # file: d.inittab-cpcd d.func-cpcd # PUT THE LINE # D1:2345:once:/root/d.inittab-cpcd # IN /etc/inittab THEN REBOOT # #VARIABLE DEV=/dev/hdb #SOURCE DRIVE TMP=/tmp/x.bin #TEMP.IMAGE FILE beep() { echo -e "\a" } beeperror() { for i in `seq 1 6`; do beep; sleep .15; done } wait_read_close() { # MAX RETRY LOOP = 100 for (( i=0; i<=100; i++ )) do if setcd -i $DEV | grep open >> /dev/null; then # SLEEP 1 SECONDS beep; sleep 3 else #TRY CLONE MODE readom -v dev=$DEV f=$TMP -clone retries=128 ts=128k ISCLONE=$? if [ $ISCLONE -ne 0 ]; then readom -v dev=$DEV f=$TMP retries=128 ts=128k fi return fi done eject -t $1 /sbin/shutdown -h now return } rm -rf $TMP #CHECK 1ST CDR IS ORIGINAL CD THEN DUP. TO /tmp while ! [ -s $TMP ] do eject $DEV wait_read_close $DEV beep done # CALL MULTIPLE INSTANCE IN 3 DRIVES /dev/hdb /dev/hdc AND /dev/hdd /root/d.func-cpcd /dev/hdb $ISCLONE 1 $TMP & /root/d.func-cpcd /dev/hdc $ISCLONE 1 $TMP & /root/d.func-cpcd /dev/hdd $ISCLONE 1 $TMP & wait /sbin/shutdown -h now
# chmod 755 /root/d.inittab-cpcd
สร้างไฟล์ฟังก์ชั่นเขียนซีดีแบบขนาน
# vi /root/d.func-cpcd
#!/bin/bash DEV=$1 ISCLONE=$2 SPEED=$3 TMP=$4 beep() { echo -e "\a" } 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 if [ $ISCLONE -ne 0 ]; then wodim -v gracetime=2 dev=$DEV speed=$SPEED driveropts=burnfree -overburn -eject $TMP else wodim -v gracetime=2 dev=$DEV speed=$SPEED driveropts=burnfree -raw96r -clone -overburn -eject $TMP fi # LAST CHECK WRITING if setcd -i $DEV | grep 'error' >> /dev/null; then beeperror; sleep 3 else eject $DEV return fi fi done #END PROG eject -t $1 exit 1 } if [ ! $1 ] && [ ! $2 ] && [ ! $3 ] ; then echo " USAGE : $0 DRIVE SPEED TEMP-IMG" echo " EXAM1 : $0 /dev/hdb 8 /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 $DEV beepwrite done
# chmod 755 /root/d.func-cpcd
แก้ไข inittab ให้เรียกการทำงานตอนเริ่มต้นเปิดเครื่อง
# vi /etc/inittab
... #COPY CD D1:2345:once:/root/d.inittab-cpcd
เสร็จแล้ว บูตเครื่องแล้วใช้ได้เลย
เที่ยวนี้มีเวลาทดสอบน้อย ฝากทดสอบกันเองนะครับ
ปรับปรุงครั้งที่ 1
# vi d.inittab-cpcd
#!/bin/bash # THIS IS THE CD COPIER PROGRAM # - REQUIRE PACKAGE: setcd eject cdrecord(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 "\a" } 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
# vi d.func-cpcd
#!/bin/bash # THIS IS THE CD COPIER PROGRAM # - REQUIRE PACKAGE: setcd eject cdrecord(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 "\a" } 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 cdrecord -clone gracetime=2 -raw96r dev=$DEV speed=$SPEED driveropts=burnfree -overburn -multi -xa1 -eject $TMP else cdrecord 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
งานต้นฉบับสำหรับส่งโรงพิมพ์ สำหรับหน้าที่มีภาพชิดขอบ เราจำเป็นต้องเผื่อขอบให้มากกว่าขนาดกระดาษจริงด้านละ 3 มม. เพื่อกันตัดขอบพลาด ดังนั้นเวลาเตรียมต้นฉบับ ต้องเผื่อขนาดหน้าไว้ +6 มม.เสมอ
เราจะทำ Inkscape Script Extensions ด้วยไพธอน เพื่อใช้ในการนี้ในการรันแปลงไฟล์ภาพทีละหลาย ๆ ไฟล์ได้
สคริปต์ตัวอย่าง จะเป็นสคริปต์ที่ใช้ขยายหน้ากระดาษของ Inkscape ออกด้านละ 3 มม. พร้อมกับขยับวัตถุทุกอย่างขึ้นข้างบนและไปทางขวา ด้านละ 3 มม. (ทั้งนี้เวลาเตรียมงานขั้นต้น เราจะจัดให้ลงหน้าตรงกลาง และเผื่อขนาดภาพพื้นหลังออกไปทางขอบทุกด้าน ซึ่งก็เป็นธรรมชาติของการทำงานอยู่แล้ว)
จะตั้งชื่อส่วนขยายนี้ว่า expand_3mm
จะต้องสร้างไฟล์ 2 ไฟล์ คือ Extension description file (.inx) และ Python script file (.py) แล้วใส่ลงในไดเรคทอรี่ ~/.config/inkscape/extensions/
หรือหากต้องการให้ใช้ได้กับทุกคนก็ใส่ลงใน /usr/share/inkscape/extensions
ดังนี้
$ vi ~/.config/inkscape/extensions/expand_3mm.inx
<inkscape-extension> <_name>Expand 3mm</_name> <id>org.ekips.filter.expand_3mm</id> <dependency type="executable" location="extensions">expand_3mm.py</dependency> <dependency type="executable" location="extensions">inkex.py</dependency> <dependency type="executable" location="extensions">simpletransform.py</dependency> <effect> <object-type>all</object-type> <effects-menu> <submenu _name="Example"/> </effects-menu> </effect> <script> <command reldir="extensions" interpreter="python">expand_3mm.py</command> </script> </inkscape-extension>
$ vi ~/.config/inkscape/extensions/expand_3mm.py
#!/usr/bin/env python # These two lines are only needed if you don't put the script directly into the installation directory import sys sys.path.append('/usr/share/inkscape/extensions') # We will use the inkex module with the predefined Effect base class. import inkex, simpletransform class Expand3mmEffect(inkex.Effect): """ Example Inkscape effect extension. """ def __init__(self): """ Constructor. """ # Call the base class constructor. inkex.Effect.__init__(self) def effect(self): """ Effect behaviour. """ #MOVE 3mm,3mm add = 10.629878067 #3mm transformation = 'translate(%s,%s)' % (add,add,) transform = simpletransform.parseTransform(transformation) if self.selected: for id, node in self.selected.iteritems(): simpletransform.applyTransformToNode(transform, node) #EXPAND 6mm svg = self.document.getroot() width = float(svg.get('width')) + (add * 2) #6mm height = float(svg.get('height')) + (add * 2) #6mm svg.set('width','%s' % (width,)) svg.set('height','%s' % (height,)) # Create effect instance and apply it. effect = Expand3mmEffect() effect.affect() # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99
เสร็จแล้ว
ทดสอบว่าสคริปต์ใช้ได้หรือไม่ ด้วยการลองเปิด inkscape ดู จะเห็นอยู่ในเมนู Extensions -> Example -> Expand 3mm
หรือผ่านบรรทัดคำสั่งว่า
$ inkscape --verb-list | grep expand_3mm
จะขึ้นมาว่า
org.ekips.filter.expand_3mm: Expand 3mm org.ekips.filter.expand_3mm.noprefs: Expand 3mm (No preferences)
เปิดไฟล์ demo.svg -> Select All in All Layers -> ขยายขนาด -> บันทึกกลับ -> ปิด inkscape
$ inkscape demo.svg --verb=EditSelectAllInAllLayers --verb=org.ekips.filter.expand_3mm --verb=FileSave --verb=FileClose
เสร็จแล้ว
/usr/share/inkscape/extensions
รวมทั้งตัว inkex.py ด้วยเอามาจาก
for i in *.mp3; do mv "$i" `echo $i | tr ' ' '_'`; done
for i in *.[Mm][Pp]3; do mv "$i" `echo $i | tr '[A-Z]' '[a-z]'`; done
for i in *.MP3; do mv "$i" "`basename "$i" .MP3`.mp3"; done
ffmpeg -i infile.xxx -acodec pcm_s16le -ar 44100 -ac 2 -f wav outfile.wav
(มีความรู้สึกว่าแปลงด้วย ffmpeg เสียงครบกว่าแปลงด้วย mplayer ซึ่งเสียงจะนุ่มลงเล็กน้อย)
ถ้าแปลงทีละไดเรกทอรี่ คำสั่งคือ
for i in *; do ffmpeg -i "$i" -acodec pcm_s16le -ar 44100 -ac 2 \ -f wav "$i.wav"; done
แทรกนิด แปลงจาก mp3 เป็น mp3 ผ่านไลบรารี libmp3lame แบบเล็ก แต่ฟังได้ดี
for i in *; do ffmpeg -i "$i" -acodec libmp3lame -ab 24k -ar 11025 -ac 2 \ "mp3/$i"; done
for i in *.mp3; do mpg321 -w "`basename "$i" .mp3`.wav" "$i"; done
for i in *.mp3; do madplay -o "`basename "$i" .mp3`.wav" "$i"; done
for i in *.mp3; do lame --decode "$i" "`basename "$i" .mp3`.wav"; done
for i in *.ogg ; do ogg123 -d wav -f "`basename "$i" .ogg`.wav" "$i"; done
for i in *.wma; do mplayer -vo null -vc dummy -af resample=44100 \ -ao pcm:waveheader:file="${i%.wma}.wav" "$i" ; done
aptitude install faac faac -b 16 -c 44100 -w --title "TITLE" --artist "ARTIST" INFILE.wav
ได้ไฟล์ออกมาเป็น INFILE.m4a (คุณภาพดีกว่าแปลงจาก ffmpeg)
คำสั่งคือ
normalize-audio -m *.wav
หรือ
mp3gain -c -r *mp3
เกลี่ยเสียง ลดเสียงทุ้มลง 18db เพิ่มเสียงแหลม 3db
sox --norm INFILE.wav OUTFILE.wav bass -24 treble +3
cdda2wav -D /dev/cdrom -t TRACK 01
update
$ ffmpeg -i sound.mp3 -ar 16000 -ab 8 -ac 1 sound.wma
$ ffmpeg -i sound.mp3 -acodec wmav2 -ab 24k -ac 1 -ar 11025 sound.wma
$ ffmpeg -i sound.rm sound.wav
รูปแบบที่เลือกใช้
เลือกใช้ mp3 เนื่องจากแพร่หลาย และไม่ผูกติดกับวินโดวส์
เลือกใช้ตัวแปลงคือ lame เนื่องจากเสียงนุ่มนวลกว่า
$ lame -h -b 16 INFILE.XXX OUTFILE.mp3
$ lame -h -b 128 INFILE.XXX OUTFILE.mp3
$ for i in *mp3; do mplayer -vo null -vc dummy -af resample=44100 -ao pcm:waveheader:file=/tmp/x.wav "$i"; ffmpeg -i /tmp/x.wav -acodec libmp3lame -ab 32k -ar 11025 -ac 2 "24k/$i"; done; rm /tmp/x.wav
$ lame --mp3input -m m --resample 24 -h INFILE.mp3 OUTFILE.mp3
$ ffmpeg -i INFILE.mpg -f 3gp -vcodec mpeg4 -b 150000 -s 320x240 -r 18 -acodec libfaac -ab 64000 -ar 24000 -ac 2 OUTFILE.3gp
หมายเหตุ
การติดตั้งแพกเกจที่เกี่ยวข้อง
$ sudo aptitude install ffmpeg
$ sudo aptitude install mpg321
$ sudo aptitude install madplay
$ sudo aptitude install lame
$ sudo aptitude install vorbis-tools
$ sudo aptitude install mplayer
$ sudo aptitude install normalize-audio
$ sudo aptitude install cdda2wav