Video is generally stored as a collection of compressed streams in a container file. Each stream may be video images, an audio track, or other data (such as subtitles) that are synchronized with each other. The container (file format) determines how those streams are stored. IDLffVideoRead and IDLffVideoWrite support the formats listed in Video Formats.

If the file format is not specified with the FORMAT keyword in the IDLffVideoWrite::Init method, IDLffVideoWrite attempts to guess the intended file format from the filename.

The WRITE_VIDEO function provides a separate wrapper for IDLffVideoWrite. See the WRITE_VIDEO topic for more information and examples on using this function.

In the following example, you can change the extension of the filename to try the different formats.

PRO VIDEO_EXAMPLE_FILE_FORMAT
  width = 500
  height = 500
  fps = 20
   
  surf = SURFACE(/TEST, /BUFFER, DIMENSIONS=[width,height])
   
  ; Each of the following lines produces a file in
  ; a different format.
  oVid = IDLffVideoWrite('video_example_file_format.webm')
  ;oVid = IDLffVideoWrite('video_example_file_format.swf')
  ;oVid = IDLffVideoWrite('video_example_file_format.bin', FORMAT='mp4')
  ; Prints out a list of supported file formats
  PRINT, "Supported file formats: ", oVid.GetFormats()
  vidStream = oVid.AddVideoStream(width, height, fps)
   
  FOR i = 0, 90 do begin
    surf.Rotate, 4, /YAXIS
    frame = surf.CopyWindow()
    !NULL = oVid.Put(vidStream, frame)
  ENDFOR
   
  oVid = 0
END

Compression (Codecs)


There are different ways to compress each of these formats. A codec (COder/DECoder) is software for compressing and decompressing a stream. Support for different audio and video codecs vary by format; see Video Codec Formats for details. If the codecs are not explicitly set, IDLffVideoWrite will try to choose a default appropriate for the file format. Some common video codecs are MPEG-2 Video, MPEG-4 Visual, and H.264. Common audio codecs are MP2, MP3, FLAC, and PCM. Some codecs are better than others, some are more widely supported than others, and some have strengths and weaknesses that make them suited for specific purposes.

In general, which codec you use plays a big role in file size and quality, but the choice of file format does not matter, so long as it supports your chosen codecs and it is supported by the player software.

Each file format supports a different set of codecs for its streams. It is suggested that you use MP4 or AVI files with MPEG-4 compressed video. The following example makes an AVI file using the default bitrates and codecs: 2 Mbps MPEG-4 video, and 128 Kbps MP2 audio.

 
; A helper function to create the audio
FUNCTION create_audio, offset, length, scale
  t = (lindgen(length) + offset*length) / scale
  s = (t/(2^7) OR t OR t/(2^6)) * 10 + 4 * (t AND t/(2^13) or t/(2^6))
  RETURN, FIX(s, type=1) * (2^5)
END
 
; Now create the video
PRO VIDEO_EXAMPLE_DEFAULT_SETTING
  width      = 500
  height     = 500
  fps        = 20
  sampleRate = 44100
  surf = SURFACE(/TEST, /BUFFER, DIMENSIONS=[width,height])
  oVid = IDLffVideoWrite('video_example_default_setting.avi')
  vidStream = oVid.AddVideoStream(width, height, fps)
  audStream = oVid.AddAudioStream(sampleRate)
   
  for i = 0, 100 do begin
    surf.Rotate, 4, /YAXIS
   
    audio = create_audio(i, sampleRate/fps, 5)
    frame = surf.CopyWindow()
   
    !NULL = oVid.Put(audStream, audio)
    !NULL = oVid.Put(vidStream, frame)
  ENDFOR
   
  oVid = 0
END

You can explicitly set the codec used to compressed audio and video. You can also set what bitrate the codec should attempt to compress down to, in bits per second. In general, quality and file size are directly proportional to bitrate. Bitrate sets a goal for the codec; actual results may be higher or lower. Different codecs respond to adjusted bitrates differently; you may need to experiment to find the right tradeoff for your application.

The following example prints the supported audio and video codecs, then sets the codec and bitrate.

PRO VIDEO_EXAMPLE_CUSTOM_SETTING
  width = 500
  height = 500
  fps = 20
  surf = SURFACE(/TEST, /BUFFER, DIMENSIONS=[width,height])
  oVid = IDLffVideoWrite('video_example_custom_setting.avi')
   
  ; Prints out a list of supported file formats
  PRINT, "Supported audio codecs: ", oVid.GetCodecs(/AUDIO)
  PRINT, "Supported video codecs: ", oVid.GetCodecs(/VIDEO)
   
  ; Uses the msmpeg4v2 codec, rather than the default mpeg4.
  ; Also, sets a very low bitrate of 200Kbps to show how file
  ; size is reduced and quality suffers.  Try comparing with
  ; a fairly high setting of 4Mbps (4000000).
  vidStream = oVid.AddVideoStream(width, height, fps, $
    CODEC='msmpeg4', BIT_RATE=200000)
   
  FOR i = 0, 90 DO BEGIN
    surf.Rotate, 4, /YAXIS
    frame = surf.CopyWindow()
    !NULL = oVid.Put(vidStream, frame)
  ENDFOR
   
  oVid = 0
END

It is also possible to output audio-only files, shown in the following example:

; A helper function to create the audio
FUNCTION make_music, offset, length, scale
  t = (lindgen(length) + offset*length) / scale
  s = (t/(2^7) OR t OR t/(2^6)) * 10 + 4 * (t AND t/(2^13) or t/(2^6))
  return, fix(s, type=1) * (2^5)
end
 
; Now create the audio file
PRO audio_example
  sampleRate = 44100
  oVid = IDLffVideoWrite('audio_example.wav')
  audStream = oVid.AddAudioStream(sampleRate)
   
  FOR i = 0, 60 DO BEGIN
    audio = make_music(i, sampleRate, 5)
    !NULL = oVid.Put(audStream, audio)
  ENDFOR
   
  oVid = 0
END

Note: If you have problems playing videos, try using the open source VLC Media Player (http://www.videolan.org/).

To replace IDL's version of FFmpeg with another one, see the next section.

Replacing the FFmpeg Version

IDLffVideoWrite uses the open-source FFmpeg library to handle video file formats and compression. FFmpeg supports many file formats, audio codecs, and video codecs, but there are certain features which are not included in the version that comes with IDL. Examples of these features are AAC audio, MP3 audio, or H.264 video encoding.

IDLffVideoRead and IDLffVideoWrite permit replacement of the default version of FFmpeg in IDL with a different one. To replace the IDL version of FFmpeg, the following files would need to be replaced. They are located in IDL_DIR\bin\bin.x86_64.

  • avcodec-*.dll
  • avformat-*.dll
  • avutil-*.dll
  • swscale-*.dll

Keep the version of the file the same. You can check if your replacement was successful by printing out the values of IDLffVideoWrite::GetCodecs() and ::GetFormats() before and after; the lists of supported codecs and formats should become much longer after you replace the files. See the PRESET keyword in IDLffVideoWrite for more options with H.264.

NV5 Geospatial Solutions ASSUMES NO RISKS OR LIABILITIES ASSOCIATED WITH ANY SUCH REPLACEMENTS.

The following example uses a replaced FFmpeg version and specifies the 'libx264' codec:

; Create the video
PRO video_example_custom_ffmpeg
  width = 500
  height = 500
  fps = 20
  surf = surface(/TEST, /BUFFER, DIMENSIONS=[width,height])
  oVid = IDLffVideoWrite('video_example_custom_ffmpeg.mp4')
  vidStream = oVid.AddVideoStream(width, height, fps, $
    CODEC='libx264', PRESET='medium')
  FOR i = 0, 200 DO BEGIN
  surf.Rotate, 4, /YAXIS
    frame = surf.CopyWindow()
  !NULL = oVid.Put(vidStream, frame)
  ENDFOR
  oVid = 0
END

See Also


IDLffVideoRead, IDLffVideoWrite, QUERY_VIDEO, READ_VIDEO, WRITE_VIDEO