Audio information is often not less important part of the movie than the video data itself. This section describes how to maintain audio data with AVI Processor Add-on for Graphics Mill.
AVI Processor Add-on audio support is not as rich as video one. It has the following basic functionality:
All audio-related functionality is concentrated in the single class called Aurigma.GraphicsMill.Codecs.AviAudioManager. This class is returned by the AviReader.AudioManager and AviWriter.AudioManager properties. It has a number of members which can be used both to read and write the audio data from/to the AVI file.
If you retrieve the audio manager object from the reader, you can use only those members which extract the audio data. In particular:
Contrarily, if the audio manager object is retrieved from the writer, you can use only those members which are responsible for adding audio data to the AVI file:
An AVI file can contain more than one audio track (stream). When the movie is playing, the user selects one of audio tracks (if the player supports this feature). It is widely used when the movie is translated into another language. In this case the AVI file can contain both original sound track and the translation.
Not all players support multiple audio tracks. Such players just use the very first audio track and disregard others. That's why it is recommended to add the most essential audio track to the very first position.
When you open the AVI file with reader, you can get the number of audio streams with the AudioStreamCount property. Each method which gets access to some specific stream requires to pass a stream index. The stream index should be a number in the range from 0 to AudioStreamCount - 1. See two next paragraphs for more details.
If you want to extract an audio stream to a separate file, you should use the ExportAudioStream method. You pass an index of the stream and the destination of the export. As a destination you can specify file name or an instance of the System.IO.Stream class. This way you can save the audio track not only to a file, but to a database or whatever else destination. Also, you can specify the duration of the result audio data.
The code snippet below demonstrates how to save first 10 seconds from the first audio track of the AVI file (if presented).
' It is assumed that the reader variable contains an instance of the ' Aurigma.GraphicsMill.Codecs.AviReader class opened on the necessary ' AVI file. ' Make sure that the AVI file is not a silent movie. If reader.AudioManager.AudioStreamCount > 0 Then ' Last parameter is a duration of the output file. It is measured ' in 1/100 of second. To get 10 seconds, set the value = 1000. ' If you omit it or set it to 0, the entire audio track will be saved. reader.AudioManager.ExportAudioStream(0, "C:\Temp\sound_10sec.wav", 0, 1000) End If
// It is assumed that the reader variable contains an instance of the // Aurigma.GraphicsMill.Codecs.AviReader class opened on the necessary // AVI file. // Make sure that the AVI file is not a silent movie. if (reader.AudioManager.AudioStreamCount > 0) { // Last parameter is a duration of the output file. It is measured // in 1/100 of second. To get 10 seconds, set the value = 1000. // If you omit it or set it to 0, the entire audio track will be saved. reader.AudioManager.ExportAudioStream(0, @"C:\Temp\sound_10sec.wav", 0, 1000); }
Several methods of the audio manager enable you to get some information about the audio track. The code snippet below displays information about the first track.
' It is assumed that the reader variable contains an instance of the ' Aurigma.GraphicsMill.Codecs.AviReader class opened on the necessary ' AVI file. ' Make sure that the AVI file is not a silent movie. If reader.AudioManager.AudioStreamCount > 0 Then System.Windows.Forms.MessageBox.Show(String.Format( _ "Length: {0} [hh:mm:ss]" & vbNewLine & "Bit Depth:{1}" & _ vbNewLine & "Channels: {2}", _ TimeSpan.FromSeconds(reader.AudioManager.GetDuration(0) \ 100L), _ reader.AudioManager.GetBitsPerSample(0), _ reader.AudioManager.GetChannelCount(0))) End If
// It is assumed that the reader variable contains an instance of the // Aurigma.GraphicsMill.Codecs.AviReader class opened on the necessary // AVI file. // Make sure that the AVI file is not a silent movie. if (reader.AudioManager.AudioStreamCount > 0) { System.Windows.Forms.MessageBox.Show( String.Format("Length: {0} [hh:mm:ss]\nBit Depth:{1}\nChannels: {2}", TimeSpan.FromSeconds(reader.AudioManager.GetDuration(0) / 100), reader.AudioManager.GetBitsPerSample(0), reader.AudioManager.GetChannelCount(0))); }
Now let's examine how to use audio manager with a writer.
If you need to add an audio stream, you should use the AddAudioStream. Here you should specify the source to get the audio data from as well as few other parameters. It returns the index of the stream which has been added with this call.
You can use the following sources of the audio data:
You can also specify the duration of required audio stream measured in 1/100 of seconds. E.g. if you set the duration argument to 1000, it will take first 10 seconds.
Another parameter called cutToVideoDuration
is a boolean value which specifies
whether to truncate the audio data if its length will be larger than a length of the video
data. If audio is longer than video and:
cutToVideoDuration = false
, then when all frames are displayed, the player
software will display the latest frame and wait until the audio track finishes.cutToVideoDuration = true
, then AVI Processor Add-on will truncate the audio data to be of the same length
as video.When you set the cutToVideoDuration
to true
, you should bear
in mind that the truncation occurs in the moment when you call the AddAudioStream method. All
calculations will be done for the video data which is already added to the writer. If you
add more frames after you put the audio data, these frames will not be dubbed in.
That's why you should put the audio streams after you added all video data.
The code snippet below demonstrates how to add one audio stream. If you need to add more audio streams, you should just call AddAudioStream per each track.
' It is assumed that reader and writer variables ' contains opened and properly initialized ' Aurigma.GraphicsMill.Codecs.AviReader and ' Aurigma.GraphicsMill.Codecs.AviWriter respectively. ' You should add video frames before you add audio. Dim frame As Aurigma.GraphicsMill.Codecs.IFrame For Each frame In reader writer.AddFrame(frame) Next ' This line adds the audio track. If the WAV file ' has larger duration than the result AVI, writer ' will truncate it (because of the second argument). writer.AudioManager.AddAudioStream("C:\Temp\SoundTrack.wav", True) writer.Close() reader.Close()
// It is assumed that reader and writer variables // contains opened and properly initialized // Aurigma.GraphicsMill.Codecs.AviReader and // Aurigma.GraphicsMill.Codecs.AviWriter respectively. // You should add video frames before you add audio. foreach (Aurigma.GraphicsMill.Codecs.IFrame frame in reader) { writer.AddFrame(frame); } // This line adds the audio track. If the WAV file // has larger duration than the result AVI, writer // will truncate it (because of the second argument). writer.AudioManager.AddAudioStream(@"C:\Temp\SoundTrack.wav", true); writer.Close(); reader.Close();
When you need to glue an audio track from several files, you should use the AppendAudioStream method. It has the same arguments as the AddAudioStream and an extra one - the index of the stream you append the sound to. It is demonstrated in the code snippet below:
' It is assumed that reader and writer variables ' contains opened and properly initialized ' Aurigma.GraphicsMill.Codecs.AviReader and ' Aurigma.GraphicsMill.Codecs.AviWriter respectively. Dim frame As Aurigma.GraphicsMill.Codecs.IFrame For Each frame In reader writer.AddFrame(frame) Next ' Take first 10 seconds from the SoundTrack.wav and all the rest audio data ' from SoundTrack_End.wav. Note, it is assumed that these WAV files has enough ' length. Say, if the first WAV is shorter than 10 seconds, the second WAV will ' be played from the end of this WAV rather than from 10th second. Dim index As Integer index = writer.AudioManager.AddAudioStream("C:\Temp\SoundTrack.wav", 0, 1000, True) writer.AudioManager.AppendAudioStream(index, "C:\Temp\SoundTrack_End.wav", True) writer.Close() reader.Close()
// It is assumed that reader and writer variables // contains opened and properly initialized // Aurigma.GraphicsMill.Codecs.AviReader and // Aurigma.GraphicsMill.Codecs.AviWriter respectively. foreach (Aurigma.GraphicsMill.Codecs.IFrame frame in reader) { writer.AddFrame(frame); } // Take first 10 seconds from the SoundTrack.wav and all the rest audio data // from SoundTrack_End.wav. Note, it is assumed that these WAV files has enough // length. Say, if the first WAV is shorter than 10 seconds, the second WAV will // be played from the end of this WAV rather than from 10th second. int i = writer.AudioManager.AddAudioStream(@"C:\Temp\SoundTrack.wav", 0, 1000, true); writer.AudioManager.AppendAudioStream(i, @"C:\Temp\SoundTrack_End.wav", true); writer.Close(); reader.Close();
It is recommended to append WAV files with the same compression as the audio stream has. Although AVI Processor Add-on tries to convert the appended audio data automatically, it may fail (if appropriate VfW codecs are not installed).