private static IMFTranscodeProfile CreateProfile(AudioFormat audioOutput, VideoFormat videoOutput, Guid containerType) { IMFTranscodeProfile profile = null; // Create a transcode profile MFHelper.MFCreateTranscodeProfile(out profile); // Create and set the audio attributes profile.SetAudioAttributes(SimpleFastEncode.CreateAudioAttributes(audioOutput)); // Create and set the video attributes profile.SetVideoAttributes(SimpleFastEncode.CreateVideoAttributes(videoOutput)); // Create the container attributes IMFAttributes containerAttributes = null; MFHelper.MFCreateAttributes(out containerAttributes, 2); containerAttributes.SetUINT32(new Guid(Consts.MF_TRANSCODE_TOPOLOGYMODE), 1); containerAttributes.SetGUID(new Guid(Consts.MF_TRANSCODE_CONTAINERTYPE), containerType); // Set them in the transcoding profile profile.SetContainerAttributes(containerAttributes); return(profile); }
/// <summary> /// Starts the asychronous encode operation /// </summary> /// <param name="inputURL">Source filename</param> /// <param name="outputURL">Targe filename</param> /// <param name="audioOutput">Audio format that will be used for audio streams</param> /// <param name="videoOutput">Video format that will be used for video streams</param> /// <param name="startPosition">Starting position of the contet</param> /// <param name="endPosition">Position where the new content will end</param> public void Encode(string inputURL, string outputURL, AudioFormat audioOutput, VideoFormat videoOutput, ulong startPosition, ulong endPosition) { // If busy with other operation ignore and return if (this.IsBusy()) { return; } try { this.presentationClock = null; this.startPosition = startPosition; this.endPosition = endPosition; object objectSource = null; // Create the media source using source resolver and the input URL uint objectType = default(uint); this.mediaSource = null; // Init source resolver IMFSourceResolver sourceResolver = null; MFHelper.MFCreateSourceResolver(out sourceResolver); sourceResolver.CreateObjectFromURL(inputURL, Consts.MF_RESOLUTION_MEDIASOURCE, null, out objectType, out objectSource); this.mediaSource = (IMFMediaSource)objectSource; // Create the media session using a global start time so MF_TOPOLOGY_PROJECTSTOP can be used to stop the session this.mediaSession = null; IMFAttributes mediaSessionAttributes = null; MFHelper.MFCreateAttributes(out mediaSessionAttributes, 1); mediaSessionAttributes.SetUINT32(new Guid(Consts.MF_SESSION_GLOBAL_TIME), 1); MFHelper.MFCreateMediaSession(mediaSessionAttributes, out this.mediaSession); // Create the event handler AsyncEventHandler mediaEventHandler = new AsyncEventHandler(this.mediaSession); mediaEventHandler.MediaEvent += this.MediaEvent; // Get the stream descriptor IMFPresentationDescriptor presentationDescriptor = null; mediaSource.CreatePresentationDescriptor(out presentationDescriptor); // Get the duration presentationDescriptor.GetUINT64(new Guid(Consts.MF_PD_DURATION), out this.duration); IMFTranscodeProfile transcodeProfile = null; Guid containerType = new Guid(Consts.MFTranscodeContainerType_MPEG4); if (outputURL.EndsWith(".wmv", StringComparison.OrdinalIgnoreCase) || outputURL.EndsWith(".wma", StringComparison.OrdinalIgnoreCase)) { containerType = new Guid(Consts.MFTranscodeContainerType_ASF); } // Generate the transcoding profile transcodeProfile = SimpleFastEncode.CreateProfile(audioOutput, videoOutput, containerType); // Create the MF topology using the profile IMFTopology topology = null; MFHelper.MFCreateTranscodeTopology(this.mediaSource, outputURL, transcodeProfile, out topology); // Set the end position topology.SetUINT64(new Guid(Consts.MF_TOPOLOGY_PROJECTSTART), 0); topology.SetUINT64(new Guid(Consts.MF_TOPOLOGY_PROJECTSTOP), (endPosition == 0) ? this.duration : endPosition); // Set the session topology this.mediaSession.SetTopology((uint)Enums.MFSESSION_SETTOPOLOGY_FLAGS.None, topology); } catch (Exception ex) { this.mediaSession = null; // Fire the EncodeError event if (this.EncodeError != null) { this.EncodeError(new Exception(ex.Message, ex)); } } }