Tuesday, June 19, 2012

Use ImageMagick to create GIF file

convert -resize 50% -delay 50 -loop 0 IMG*.JPG animation.gif
convert animation.gif -crop 1152x768+0+150 crop.gif
Reduce image size: convert animation.gif -resize 100x50 small.gif

Sunday, June 3, 2012

Use FFMPEG to process video files


  • Rotate video files
  1. Download latest FFMPEG windows build from here
  2. Move all video files to be rotated (e.g. MOV files) into a subfolder. 
  3. Execute the command below from within a CMD script file (it must be executed from within a CMD script file since it will fail if copy and paste on the command line)
    FOR /F "tokens=*" %%G IN ('dir /b *.MOV') DO ffmpeg -i %%G -vf "transpose=1" -qscale 0 -s 608x1080 -y %%G.rotated.MOV
    All videos will rotate 90 degree clockwise (transpose=1). Change it to transpose=2 for counterclockwise. Height of the videos is reduced to 1080 since some media players have problem playing back files whose height is larger than 1080. Output files will append .rotated.MOV to the name of input files.
    • Set the dimension and frame rate of output file
      Command option -r set frame rate in frames/second, -s set dimension to be widthxheight
      ffmpeg -i input.mp4 -qscale 0 -r 30 -s 720x1080 -y output.mp4
    • Slow down a video
      • Copy the video to a raw bitstream format
        ffmpeg -i input.mp4 -map 0:v -c:v copy -bsf:v h264_mp4toannexb raw.h264
      • Generate new timestamps while muxing to a container
        ffmpeg -fflags +genpts -r 19.25 -i raw.h264 -c:v copy output.mp4
    • Trim video file
    1. Extract the video stream and discard the audio stream: -c copy -an option
      ffmpeg  -i input.mp4 -c copy -an noaudio.mp4
    2. Trim time: Today I have a need to trim the first 8 seconds off a mp4 video file taken by my cell phone. I found I could use -ss option to specify the start time and -t option to specify the duration of the trimmed video (below 12 seconds) and re-encode the video: 
      • ffmpeg -i input.mp4 -ss 00:00:08 -t 00:00:12 output.mp4
      • If the encoding is slow, -c copy option can skip the encoding but could generate an output file than can not seek properly
    3. Trim size: can be done with the crop filter
      • ffmpeg -i input.mp4 -filter:v "crop=out_w:out_h:x:y" output.mp4
        the arguments are as follows:
        • out_w is the width of the output rectangle
        • out_h is the height of the output rectangle
        • x and y specify the top left corner of the output rectangle relative to the top left corner of the input video
    • Convert video to GIF file
      • Generate individual frames from the video file
        mkdir frames
        ffmpeg -i out.mp4 -r 10 frames/ffout%03d.png
      • Remove unwanted frames
      • Convert frames to GIF file using ImageMagick
        convert -delay 0.25 -loop 0 frames/ffout*.png output.gif
    • Concatenate multiple video files into one
      Utilize the concat filter to concatenate multiple video files into one
      ffmpeg -f concat -i inputs.txt -c copy -y output.mp4
      The file inputs.txt should list all the video files to be concatenated (one file per line) and its contents look like the following:
      file 1.mp4
      file 2.mp4
      file 3.mp4
      file 4.mp4
    • Mix video and audio files
      I found a quick way to mix an audio mp3 file and a video/audio mp4 file by using the -map argument with ffmpeg:
      ffmpeg -i input0.mp4 -i input1.mp3 -map 0:v:0 -map 1:a:0 -c copy -shortest out output.mp4
      -map 0:v:0 for (0) input file zero, (v) video streams of the input file, (0) stream zero (first) of the video streams
      -map 1:a:0 for (0) input file one, (a) audio streams of the input file,  (0) stream zero (first) of the audio streams
      -c copy copy the desired streams to the output file instead of encoding them to maintain the same quality
      -shortest designate the duration of the output file to be the same as the shortest one among input streams