/// <summary> /// Return a list of all the system profiles. /// </summary> /// <returns></returns> public static String QuerySystemProfiles() { IWMProfileManager pm; IWMProfileManager2 pm2; uint hr = WMFSDKFunctions.WMCreateProfileManager(out pm); pm2 = (IWMProfileManager2)pm; pm2.SetSystemProfileVersion(WMT_VERSION.WMT_VER_7_0); pm2 = null; uint pCount; pm.GetSystemProfileCount(out pCount); IWMProfile profile; StringBuilder sb = new StringBuilder(500); sb.Append("System Profile count: " + pCount.ToString() + "\n\r"); String name; for (uint i = 0; i < pCount; i++) { pm.LoadSystemProfile(i, out profile); name = GetProfileName(profile); sb.Append((i + 1).ToString() + " " + name + "\n\r"); } return(sb.ToString()); }
/// <summary> /// Create the basic WM writer objects. /// </summary> /// <returns></returns> public bool Init() { try { uint hr = WMFSDKFunctions.WMCreateWriter(null, out writer); writerAdvanced = (IWMWriterAdvanced)writer; writerAdvanced.SetLiveSource(1); hr = WMFSDKFunctions.WMCreateWriterNetworkSink(out netSink); } catch (Exception e) { Debug.WriteLine("Failed to create IWMWriter: " + e.ToString()); eventLog.WriteEntry("Failed to create IWMWriter: " + e.ToString(), EventLogEntryType.Error, 1000); return(false); } return(true); }
/// <summary> /// Prepare the File writer. /// </summary> /// <param name="filename"></param> /// <returns></returns> public bool ConfigFile(String filename) { if (writerAdvanced == null) { Debug.WriteLine("WriterAdvanced must exist before ConfigFile is called."); return(false); } try { uint hr = WMFSDKFunctions.WMCreateWriterFileSink(out fileSink); IntPtr fn = Marshal.StringToCoTaskMemUni(filename); fileSink.Open(fn); writerAdvanced.AddSink(fileSink); Marshal.FreeCoTaskMem(fn); } catch (Exception e) { Debug.WriteLine("Failed to configure FileSink" + e.ToString()); eventLog.WriteEntry("Failed to configure FileSink" + e.ToString(), EventLogEntryType.Error, 1000); return(false); } return(true); }
/// <summary> /// Load a WM Profile (system or custom). /// </summary> /// <param name="prxFile"></param> /// <param name="prIndex"></param> /// <returns></returns> public bool ConfigProfile(String prxFile, uint prIndex) { IWMProfile profile; uint hr = WMFSDKFunctions.WMCreateProfileManager(out profileManager); if (prxFile == "") { //use system profile Guid prg = ProfileIndexToGuid(prIndex); if (prg == Guid.Empty) { profile = null; Debug.WriteLine("Unsupported Profile index."); return(false); } try { GUID prG = WMGuids.ToGUID(prg); profileManager.LoadProfileByID(ref prG, out profile); } catch (Exception e) { eventLog.WriteEntry("Failed to load system profile: " + e.ToString(), EventLogEntryType.Error, 1000); Debug.WriteLine("Failed to load system profile: " + e.ToString()); profile = null; return(false); } } else { //use custom profile profile = LoadCustomProfile(prxFile); if (profile == null) { return(false); } } /// Tell the writer to use this profile. try { writer.SetProfile(profile); string name = GetProfileName(profile); Debug.WriteLine("Using profile: " + name); } catch (Exception e) { eventLog.WriteEntry("Failed to set writer profile: " + e.ToString(), EventLogEntryType.Error, 1000); Debug.WriteLine("Failed to set writer profile: " + e.ToString()); profile = null; return(false); } /// A slightly confusing point: Streams are subobjects of the profile, /// while inputs are subobjects of the Writer. The difference is in the /// multi-bitrate scenario where there may be multiple streams per input. /// Stream numbers start with 1, while input numbers and stream indexes begin at 0. /// If we have a profile that supports scripts, we need the stream number of /// the script stream. For audio and video, we just need input number. scriptBitrate = 0; audioInput = videoInput = 0; scriptStreamNumber = 0; audioProps = videoProps = null; /// If the profile has a script stream, find the bitrate and stream number. uint cStreams; IWMStreamConfig streamConfig; GUID streamType; profile.GetStreamCount(out cStreams); for (uint i = 0; i < cStreams; i++) { profile.GetStream(i, out streamConfig); streamConfig.GetStreamType(out streamType); if (WMGuids.ToGuid(streamType) == WMGuids.WMMEDIATYPE_Script) { streamConfig.GetStreamNumber(out scriptStreamNumber); streamConfig.GetBitrate(out scriptBitrate); } } /// Iterate over writer inputs, holding on to the IWMInputMediaProps* for each, /// so we can later configure them. Also save input numbers for audio and video here. uint cInputs; writer.GetInputCount(out cInputs); GUID guidInputType; IWMInputMediaProps inputProps = null; for (uint i = 0; i < cInputs; i++) { writer.GetInputProps(i, out inputProps); inputProps.GetType(out guidInputType); if (WMGuids.ToGuid(guidInputType) == WMGuids.WMMEDIATYPE_Audio) { audioProps = inputProps; audioInput = i; } else if (WMGuids.ToGuid(guidInputType) == WMGuids.WMMEDIATYPE_Video) { videoProps = inputProps; videoInput = i; } else if (WMGuids.ToGuid(guidInputType) == WMGuids.WMMEDIATYPE_Script) { } else { Debug.WriteLine("Profile contains unrecognized media type."); return(false); } } // We require an audio input, since that drives the timing for the whole stream. if (audioProps == null) { Debug.WriteLine("Profile should contain at least one audio input."); return(false); } return(true); }