bash script: แบ่งไฟล์สื่อออกเป็นหลาย ๆ ส่วน

เห็นคำถามเกี่ยวกับการแบ่งไฟล์สื่อออกเป็นหลายส่วนที่ ubuntuclub.com
ด้วยต้องการคลายเครียด จึงวางแผนลงมือเขียนสคริปต์ โดยคิดให้สคริปต์มีการทำงานดังต่อไปนี้

  1. หาความยาวสื่อ ด้วยโปรแกรม ffmpeg ด้วยคำสั่ง
    ffmpeg -i "$INFILE" 2>&1 | grep "Duration" | cut -d ' ' -f 4 | sed s/,//
  2. หาความยาวแต่ละส่วน (ความยาวสื่อ ÷ จำนวนส่วนที่จะแยก)
  3. ใช้ mencoder มาตัดส่วน -ss คือ seek ไปยังตำแหน่ง, -endpos คือให้ประมวลผลเท่าใด (เป็นขนาดก็ได้ เป็นจำนวนเฟรมก็ได้ เป็นค่าเวลาก็ได้)

เสร็จแล้วเขียนออกมาหยาบ ๆ และทดสอบไปเล็กน้อยว่าใช้งานได้จริงแล้วเลยเอามาบันทึกไว้กันลืมเสียหน่อย

โดยผลลัพธ์ที่ได้ออกมาเป็นสคริปต์ 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

เป็นอันพร้อมใช้งานครับ ^_^