# # The input file must be MPEG demultiplexed! # video_to_frame () { local VIDEO_SRC="$1" local VIDEO_DEST="$2" local VIDEO_FPS="$3" local VIDEO_GEOMETRY="$4" # # Root file name for temporary files. # TEMPORARY=`tempfile` # # X and Y, destination video geometry. # local VIDEO_X local VIDEO_Y # # Source video frame rate. # local SRC_VIDEO_FPS=0 # # Picture elaboration. # local PICTURE local PICTURE_X local PICTURE_Y local PICTURE_MOVE_X local PICTURE_MOVE_Y # # Frame time calculation. # local FRAME_TIME_SRC=0 local FRAME_TIME_DEST=0 local FRAME_TIME_DEST_TOTAL=0 # # Picture counters # local COUNTER=0 local COUNTER_STRING="" local PICTURE_COUNTER=0 local PICTURE_COUNTER_STRING=0 # # Get separated X and Y geometry values. # VIDEO_X=`echo $VIDEO_GEOMETRY | sed "s/x[0-9]*$//"` VIDEO_Y=`echo $VIDEO_GEOMETRY | sed "s/^[0-9]*x//"` # # Get source FPS. # SRC_VIDEO_FPS=`file $VIDEO_SRC | sed "s/^.* \([0-9.]*\) fps.*$/\1/"` # # Verify. # if [ "$SRC_VIDEO_FPS" = "" ] then false return fi # # Get single frames into JPG files, as temporary files. # It will be: $TEMPORARY.000000.jpg # $TEMPORARY.000001.jpg # ... # transcode -i $VIDEO_SRC -o $TEMPORARY. -y jpg # # Convert to the destination geometry, into PNG. # for PICTURE in $TEMPORARY.[0-9][0-9][0-9][0-9][0-9][0-9].jpg do # # Show something. # echo "[$0] Converting \"$PICTURE\"" # # Convert to the destination geometry, but keep it in scale. # convert -scale $VIDEO_GEOMETRY $PICTURE $TEMPORARY.tmp.png # # Get geometry after conversion. # PICTURE_X=`identify $TEMPORARY.tmp.png | sed "s/^.* PNG \([0-9]*\)x\([0-9]*\).*$/\1/"` PICTURE_Y=`identify $TEMPORARY.tmp.png | sed "s/^.* PNG \([0-9]*\)x\([0-9]*\).*$/\2/"` # # Check if more adaptation must be done. # if [ $PICTURE_X -eq $VIDEO_X ] && [ $PICTURE_Y -eq $VIDEO_Y ] then # # Geometry is right. # cp $TEMPORARY.tmp.png $PICTURE.png # else # # The picture must be filled somehow. # PICTURE_MOVE_X=$((($VIDEO_X - $PICTURE_X) / 2)) PICTURE_MOVE_Y=$((($VIDEO_Y - $PICTURE_Y) / 2)) # convert -geometry $VIDEO_GEOMETRY! \ -fill gray \ -colorize 100% \ $PICTURE $TEMPORARY.bg.png # composite -geometry +$PICTURE_MOVE_X+$PICTURE_MOVE_Y \ $TEMPORARY.tmp.png \ $TEMPORARY.bg.png \ $PICTURE.png # fi done # # Now, we should select the frames... # if [ "$VIDEO_FPS" = "$SRC_VIDEO_FPS" ] then # # Just make a copy. # COUNTER=0 while true do COUNTER_STRING=`printf "%06d" $COUNTER` # if [ -f $TEMPORARY.$COUNTER_STRING.jpg.png ] then cp $TEMPORARY.$COUNTER_STRING.jpg.png \ $VIDEO_DEST.$COUNTER_STRING.png else break fi COUNTER=$(($COUNTER+1)) done # else # # Calculate the frame time. # FRAME_TIME_SRC=`echo 1 / $SRC_VIDEO_FPS | bc -l` FRAME_TIME_DEST=`echo 1 / $VIDEO_FPS | bc -l` # COUNTER=0 while true do # # The time reference is the final frame rate. # The following counter is referred to the final # frame sequence. # COUNTER_STRING=`printf "%06d" $COUNTER` # # Calculate the total time reached at the # ${COUNTER}th final frame. # FRAME_TIME_DEST_TOTAL=`echo "$FRAME_TIME_DEST * $COUNTER" | bc -l` # # Calculate the right frame to take from # the original sequence. # PICTURE_COUNTER=`echo "$FRAME_TIME_DEST_TOTAL / $FRAME_TIME_SRC" | bc -l` PICTURE_COUNTER=`echo "$PICTURE_COUNTER + 0.5" | bc -l` PICTURE_COUNTER=`echo "$PICTURE_COUNTER" | sed "s/\.[0-9]*$//"` PICTURE_COUNTER_STRING=`printf "%06d" $PICTURE_COUNTER` # # Copy the selected original frame to the final # ${COUNTER}th frame. # if [ -f $TEMPORARY.$PICTURE_COUNTER_STRING.jpg.png ] then # # Show something. # printf "[$0] Source frame \"$PICTURE_COUNTER_STRING\" " printf "to destination frame \"$COUNTER_STRING\"\n" # # Copy. # cp $TEMPORARY.$PICTURE_COUNTER_STRING.jpg.png \ $VIDEO_DEST.$COUNTER_STRING.png else break fi # # Prepare to elaborate the next final frame. # COUNTER=$(($COUNTER+1)) done fi # # Remove temporary files. # rm -f $TEMPORARY* }