Creating Video
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), synchronized with each other. The container (file format) determines how those streams are stored. IDLffVideoRead and IDLffVideoWrite support the following video file formats:
- .avi: Audio Video Interleave. A very widely supported file format, which can be used to contain audio and video compressed with almost any codec.
- .flv: Adobe Flash Video. Similar to Adobe Flash, although not meant to be embedded in web pages directly, but rather used by other Flash applets.
- .mjpeg: Motion JPEG. MJPEG is widely supported by browsers such as Safari, Google Chrome, and Mozilla Firefox.
- .mp4: MPEG-4 File Format. Also widely supported.
- .swf: Adobe Flash. This is a better format for embedding in web pages, though still not very suitable for other uses.
- .webm: Google WebM. Uses the VP8 codec for video, and the Vorbis codec for audio. VP8 and Vorbis are among the best codecs, and unique in that they are completely open, royalty-free, and free of patent restrictions. However, they are not yet widely supported.
IDLffVideoWrite attempts to guess the intended file format from the filename, if one is not explicitly specified using the FORMAT keyword in the IDLffVideoWrite::Init method.
Note: 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])
oVid = IDLffVideoWrite('video_example_file_format.webm')
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 many different ways to compress each of these formats. A codec (short for COder/DECoder) is software for compressing and decompressing a stream. Each format's support for different audio and video codecs vary. 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.
Some 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 best 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 matters little so long as it supports your chosen codecs, and is supported by the player software.
Each file format supports a different set of codecs for its streams. In general, we suggest using 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.
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
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 compress audio and video. For example, you might prefer the msmpeg4v2 codec over standard mpeg4, because Windows Media Player in certain versions of Windows can play msmpeg4v2 video but not mpeg4.
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')
PRINT, "Supported audio codecs: ", oVid.GetCodecs(/AUDIO)
PRINT, "Supported video codecs: ", oVid.GetCodecs(/VIDEO)
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:
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
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 trouble playing videos, we recommend using VLC Media Player (http://www.videolan.org/). It is free, open-source, available for virtually every operating system, and can play nearly any type of video.
To replace IDL's version of FFmpeg with another one, see the following 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 (for 32-bit IDL) or IDL_DIR\bin\bin.x86_64 (for 64-bit IDL).
- 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.
Harris 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:
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