AddStream Method

Summary
Adds a stream to the profile.
Syntax
C#
C++/CLI
public void AddStream( 
   WMStreamConfig Config 
) 
public: 
void AddStream(  
   WMStreamConfig^ Config 
)  

Parameters

Config
A WMStreamConfig object that contains information about the stream to add.

Remarks

This method works by copying the stream configuration details into the profile. New streams are created using the CreateNewStream method. Configure the newly created stream using the WMStreamConfig object methods and properties before adding it to the profile using this method. A maximum of 63 streams can be added to a profile. For more information, refer to the Microsoft documentation for IWMProfile.AddStream. To add a script command stream to the file, use the WMScript.EnableScriptStream method.

Example
C#
using Leadtools; 
using Leadtools.Multimedia; 
using LeadtoolsMultimediaExamples.Fixtures; 
 
 
public bool _result = false; 
public ConvertCtrlForm _form = new ConvertCtrlForm(); 
 
const int CODEC_AUDIO_MSAUDIO = 353;       //  Microsoft WMAudio 
const int CODEC_VIDEO_WMV1 = 827739479;    //  FOURCC( 'W', 'M', 'V', '1' )  
 
public void AddStreamExample() 
{ 
   ConvertCtrl convertctrl = _form.ConvertCtrl; 
   string inFile = Path.Combine(LEAD_VARS.MediaDir, "ConvertCtrl_Source.avi"); 
   string outFile = Path.Combine(LEAD_VARS.MediaDir, "WMProfile_RemoveStreamExample.avi"); 
 
   try 
   { 
      WMProfileManager manager = new WMProfileManager(); 
 
      // create a WMProfile 
      convertctrl.WMProfile = CreateCustomProfile(manager); 
 
      // run the conversion 
      convertctrl.SourceFile = inFile; 
      convertctrl.TargetFormat = TargetFormatType.WMV; 
      convertctrl.TargetFile = outFile; 
      convertctrl.StartConvert(); 
 
      // dispose of the manager 
      manager.Dispose(); 
   } 
   catch (Exception) 
   { 
      _result = false; 
   } 
 
   // we'll loop on the state and pump messages for this example. 
   // but you should not need to if running from a Windows Forms application. 
   while (convertctrl.State == ConvertState.Running) 
      Application.DoEvents(); 
 
   // check the validity of the output file 
   MediaInfo mediaInfo = new MediaInfo(); 
   try 
   { 
      mediaInfo.SourceFile = outFile; 
      if (mediaInfo.SourceFormat == SourceFormatType.WMV) 
         _result = true; 
   } 
   catch (Exception) 
   { 
      _result = false; 
   } 
} 
 
private WMProfile CreateCustomProfile(WMProfileManager manager) 
{ 
   WMProfile profile = manager.CreateEmptyProfile(WMT_Version.V9); 
   profile.Name = "Custom Profile"; 
   profile.Description = "Custom Profile Description"; 
 
   bool added = AddAudioStream(manager, profile, 1, CODEC_AUDIO_MSAUDIO, 8000, 8000, 1, true); 
 
   // add 5 video streams with bitrates starting from 32KB/s (256Kbps). Increase the bitrate if you increase the video size 
   for (int i = 0; (i <= 4); i++) 
      AddVideoStream(manager, profile, (2 + i), CODEC_VIDEO_WMV1, 
                     (1024 * 32) + i * 1024, 400, 300, 5 * (i + 1), 0, 8); 
 
   //  mark all the video streams for mutual exclusion 
   AddMutexObject(profile, 2, 5); 
   return profile; 
} 
 
private bool AddVideoStream(WMProfileManager manager, 
                            WMProfile profile, 
                            int streamnum, 
                            long fourcc, 
                            int bitrate, 
                            int width, 
                            int height, 
                            int fps, 
                            int quality, 
                            int secperkey) 
{ 
   WMStreamConfig codecformat; 
   MediaType mediatype; 
   VideoInfoHeader vih; 
   bool candidate = false; 
   VideoInfoHeader candidatevih = new VideoInfoHeader(); 
   MediaType candidatemt = null; 
   WMStreamConfig candidatestream = null; 
   bool added = false; 
   byte[] viharr = new byte[88]; 
   int codecs = manager.GetCodecInfoCount(Constants.MEDIATYPE_Video); 
   string sinfo = string.Empty; 
 
   // width and height must be even 
   if ((width & 1) != 0) 
      width++; 
   if ((height & 1) != 0) 
      height++; 
 
   //  search for matching codec until I find a candidate 
   for (int codecindex = 0; codecindex < codecs && !candidate; codecindex++) 
   { 
      sinfo += manager.GetCodecName(Constants.MEDIATYPE_Video, codecindex); 
      int formats = manager.GetCodecFormatCount(Constants.MEDIATYPE_Video, codecindex); 
 
      for (int formatindex = 0; formatindex < formats; formatindex++) 
      { 
         sinfo += manager.GetCodecFormatDesc(Constants.MEDIATYPE_Video, codecindex, formatindex); 
         codecformat = manager.GetCodecFormat(Constants.MEDIATYPE_Video, codecindex, formatindex); 
         mediatype = codecformat.GetMediaType(); 
 
         if (mediatype.FormatType == Constants.FORMAT_VideoInfo) 
         { 
            vih = mediatype.GetVideoFormatData(); 
            if (vih.bmiHeader.biCompression == fourcc) 
            { 
               candidate = true; 
               candidatevih = vih; 
               candidatemt = mediatype; 
               candidatestream = codecformat; 
               // stop searching if I found a candidate 
               break; 
            } 
         } 
      } 
   } 
   if (candidate) 
   { 
      //  modify the selected codec to support this bitrate and size 
      candidatevih.dwBitRate = bitrate; 
      candidatevih.rcSource.Right = width; 
      candidatevih.rcSource.Bottom = height; 
      candidatevih.rcTarget.Right = width; 
      candidatevih.rcTarget.Bottom = height; 
      candidatevih.bmiHeader.biWidth = width; 
      candidatevih.bmiHeader.biHeight = height; 
      // since fps is integer, 10000000/fps always fits in a 32-bit value, so lowpart=10000000/fps and high part is always 0 
      candidatevih.AvgTimePerFrame.lowpart = 10000000 / fps; 
      candidatevih.AvgTimePerFrame.highpart = 0; 
 
      StructToByteArray(candidatevih, ref viharr); 
 
      // candidatevih is a copy of the media type, so updating candidatevih is not enough to update the media type. 
      // Call SetVideoFormatData to copy the updated information from candidatevih to the video format data inside candidatemt 
      // If you just change candidatevih without calling candidatemt.SetVideoFormatData,  
      // candidatemt is an empty media type with no width and height 
      candidatemt.SetVideoFormatData(candidatevih, null, 0); 
 
      candidatestream.Quality = quality; 
      candidatestream.MaxKeyFrameSpacing = secperkey; 
      candidatestream.StreamNumber = streamnum; 
      candidatestream.StreamName = "Video Stream"; 
      candidatestream.ConnectionName = "Video"; 
      candidatestream.Bitrate = bitrate; 
      candidatestream.SetMediaType(candidatemt); 
      profile.AddStream(candidatestream); 
      added = true; 
   } 
   return added; 
} 
 
private bool AddAudioStream(WMProfileManager manager, 
                            WMProfile profile, 
                            int streamnum, 
                            int formattag, 
                            int prefbitrate, 
                            int samplespersec, 
                            int channels, 
                            bool withvideo) 
{ 
   WMStreamConfig codecformat; 
   MediaType mediatype; 
   WaveFormatEx wfex = new WaveFormatEx(); 
   bool added = false; 
   bool candidate = false; 
   WaveFormatEx candidatewfex = new WaveFormatEx(); 
   MediaType candidatemt = null; 
   MediaType mt; 
   WMStreamConfig stream; 
   int codecs = manager.GetCodecInfoCount(Constants.MEDIATYPE_Audio); 
 
   //  search for matching codec 
   for (int codecindex = 0; codecindex < codecs; codecindex++) 
   { 
      int formats = manager.GetCodecFormatCount(Constants.MEDIATYPE_Audio, codecindex); 
      for (int formatindex = 0; formatindex < formats; formatindex++) 
      { 
         codecformat = manager.GetCodecFormat(Constants.MEDIATYPE_Audio, codecindex, formatindex); 
         mediatype = codecformat.GetMediaType(); 
         if (mediatype.FormatType == Constants.FORMAT_WaveFormatEx) 
         { 
            ByteArrayToStruct(mediatype.Format, ref wfex); 
 
            int diff = ((wfex.nAvgBytesPerSec * 8) - prefbitrate); 
            if (diff < 250 && diff > -250 
                && wfex.nSamplesPerSec == samplespersec 
                && wfex.nChannels == channels 
                && wfex.wFormatTag == formattag) 
            { 
               if (candidate) 
               { 
                  if (withvideo) 
                  { 
                     //  
                     //  For audio/video configurations, we want to 
                     //  find the smaller blockalign. In this case,  
                     //  the blockalign is larger, so we want to 
                     //  use the old format.  
                     if (wfex.nBlockAlign <= candidatewfex.nBlockAlign) 
                     { 
                        candidatewfex = wfex; 
                        candidatemt = mediatype; 
                     } 
                  } 
                  else if (wfex.nBlockAlign >= candidatewfex.nBlockAlign) 
                  { 
                     candidatewfex = wfex; 
                     candidatemt = mediatype; 
                  } 
               } 
               else 
               { 
                  candidate = true; 
                  candidatewfex = wfex; 
                  candidatemt = mediatype; 
               } 
            } 
         } 
      } 
   } 
 
   if (candidate) 
   { 
      //  modify the selected codec to support this bitrate and format 
      mt = new MediaType(); 
      mt.Type = Constants.MEDIATYPE_Audio; 
      mt.SubType = "{" + String.Format("{0:X8}", formattag) + "-0000-0010-8000-00AA00389B71}"; 
      mt.FixedSizeSamples = true; 
      mt.TemporalCompression = false; 
      mt.SampleSize = candidatewfex.nBlockAlign; 
      mt.FormatType = Constants.FORMAT_WaveFormatEx; 
      mt.SetFormatData(-1, candidatemt.Format); 
      stream = profile.CreateNewStream(Constants.MEDIATYPE_Audio); 
      stream.StreamNumber = streamnum; 
      stream.StreamName = "Audio Stream"; 
      stream.ConnectionName = "Audio"; 
      stream.Bitrate = (candidatewfex.nAvgBytesPerSec * 8); 
      stream.SetMediaType(mt); 
      profile.AddStream(stream); 
      profile.ReconfigStream(stream); 
      added = true; 
   } 
 
   return added; 
} 
 
private void StructToByteArray(object o, ref byte[] dest) 
{ 
   try 
   { 
      //convert the structure to a byte array 
      int rawSize = Marshal.SizeOf(o); 
      GCHandle handle = new GCHandle(); 
      IntPtr buffer; 
 
      handle = GCHandle.Alloc(dest, GCHandleType.Pinned); 
      buffer = handle.AddrOfPinnedObject(); 
      Marshal.StructureToPtr(o, buffer, false); 
      handle.Free(); 
   } 
   catch (Exception ex) 
   { 
      throw ex; 
   } 
} 
 
private void ByteArrayToStruct(object buffer, ref WaveFormatEx vih) 
{ 
   try 
   { 
      GCHandle handle = new GCHandle(); 
 
      //convert the structure to a byte array 
      handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); 
      IntPtr ptr = handle.AddrOfPinnedObject(); 
      vih = (WaveFormatEx)Marshal.PtrToStructure(ptr, typeof(WaveFormatEx)); 
      handle.Free(); 
   } 
   catch (Exception ex) 
   { 
      throw ex; 
   } 
} 
 
private bool AddMutexObject(WMProfile profile, int basestream, int streamcount) 
{ 
   WMMutualExclusion excl = profile.CreateNewMutualExclusion(); 
 
   //  indicate that the streams differ by bit rate 
   excl.Type = "{D6E22A01-35DA-11D1-9034-00A0C90349BE}"; 
   for (int i = 0; i < streamcount; i++) 
      excl.AddStream(basestream + i); 
 
   //  assign the exclusion object to the profile 
   profile.AddMutualExclusion(excl); 
   return true; 
} 
 
private bool RemoveMutexObject(WMProfile profile, WMMutualExclusion excl, int basestream, int streamcount) 
{ 
   //  indicate that the streams differ by bit rate 
   excl.Type = "{D6E22A01-35DA-11D1-9034-00A0C90349BE}"; 
   for (int i = 0; i < streamcount; i++) 
      excl.RemoveStream(basestream + i); 
 
   //  remove the exclusion object from the profile 
   profile.RemoveMutualExclusion(excl); 
   return true; 
} 
 
static class LEAD_VARS 
{ 
   public const string MediaDir = @"C:\LEADTOOLS22\Media"; 
} 
Requirements

Target Platforms

See Also

Reference

WMProfile Class

WMProfile Members

Help Version 22.0.2022.12.7
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2023 LEAD Technologies, Inc. All Rights Reserved.

Leadtools.Multimedia Assembly

Products | Support | Contact Us | Intellectual Property Notices
© 1991-2023 LEAD Technologies, Inc. All Rights Reserved.