/// <summary> /// Creates an Encoding object. This is the base object to configure your encoding.<para /> /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/sections/encodings#/Encoding/PostEncodingEncodings /// </summary> /// <param name="name">This is the name of the encoding</param> /// <param name="description">This is the description of the encoding</param> private Task <Models.Encoding> CreateEncoding(string name, string description) { var encoding = new Models.Encoding() { Name = name, Description = description }; return(_bitmovinApi.Encoding.Encodings.CreateAsync(encoding)); }
/// <summary> /// Creates an IngestInputStream and adds it to an encoding<para /> /// /// The IngestInputStream is used to define where a file to read a stream from is located<para /> /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/sections/encodings#/Encoding/PostEncodingEncodingsInputStreamsIngestByEncodingId /// </summary> /// <param name="encoding">The encoding to which the stream will be added</param> /// <param name="input"> The input resource providing the input file</param> /// <param name="inputPath"> The path to the input file</param> private Task <IngestInputStream> CreateIngestInputStream(Models.Encoding encoding, Input input, String inputPath) { var ingestInputStream = new IngestInputStream() { InputId = input.Id, InputPath = inputPath, SelectionMode = StreamSelectionMode.AUTO }; return(_bitmovinApi.Encoding.Encodings.InputStreams.Ingest.CreateAsync(encoding.Id, ingestInputStream)); }
/// <summary> /// Creates an IngestInputStream and adds it to an encoding<para /> /// /// The IngestInputStream is used to define where a file to read a stream from is located<para /> /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/sections/encodings#/Encoding/PostEncodingEncodingsInputStreamsIngestByEncodingId /// </summary> /// <param name="encoding">The encoding to which the stream will be added</param> /// <param name="channelLayout"> The input resource providing the input file</param> /// <param name="audioMixInputStreamChannels"> The path to the input file</param> private Task <AudioMixInputStream> CreateAudioMixInputStream(Models.Encoding encoding, AudioMixInputChannelLayout channelLayout, List <AudioMixInputStreamChannel> audioMixInputStreamChannels) { var audioMixInputStream = new AudioMixInputStream() { ChannelLayout = channelLayout, AudioMixChannels = audioMixInputStreamChannels }; return(_bitmovinApi.Encoding.Encodings.InputStreams.AudioMix.CreateAsync(encoding.Id, audioMixInputStream)); }
/// <summary> /// Creates a BroadcastTS muxing with one video and multiple audio streams<para /> /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/sections/encodings#/Encoding/PostEncodingEncodingsMuxingsBroadcastTsByEncodingId /// </summary> /// <param name="encoding">The encoding to which the muxing will be added</param> /// <param name="videoStream">The output resource to which the unencrypted segments will be written to</param> /// <param name="audioStreams">The output path where the unencrypted segments will be written to</param> /// <param name="output">The video stream to be included in the muxing</param> /// <param name="outputPath">A map of audio streams to be included in the muxing, with the key value /// specifying their language tag</param> private Task CreateBroadcastTsMuxing(Models.Encoding encoding, Stream videoStream, Dictionary <string, Stream> audioStreams, Output output, string outputPath) { var broadcastTsMuxing = new BroadcastTsMuxing() { Filename = "broadcast.ts", Name = "BroadcastTS muxing", SegmentLength = 4.0, Outputs = new List <EncodingOutput>() { BuildEncodingOutput(output, outputPath) }, Configuration = new BroadcastTsMuxingConfiguration() }; // handle video stream var videoInputStreamConfiguration = new BroadcastTsVideoInputStreamConfiguration() { StreamId = videoStream.Id, }; broadcastTsMuxing.Configuration.VideoStreams.Add(videoInputStreamConfiguration); broadcastTsMuxing.Streams.Add(new MuxingStream() { StreamId = videoStream.Id }); // handle audio streams var pid = 2000; foreach (var audioStream in audioStreams) { var audioInputStreamConfiguration = new BroadcastTsAudioInputStreamConfiguration() { StreamId = audioStream.Value.Id, PacketIdentifier = pid++, Language = audioStream.Key }; broadcastTsMuxing.Configuration.AudioStreams.Add(audioInputStreamConfiguration); broadcastTsMuxing.Streams.Add(new MuxingStream() { StreamId = audioStream.Value.Id }); } return(_bitmovinApi.Encoding.Encodings.Muxings.BroadcastTs.CreateAsync(encoding.Id, broadcastTsMuxing)); }
/// <summary> /// Creates an HLS default manifest that automatically includes all representations configured in the encoding. /// <para /> /// API endpoints: /// https://bitmovin.com/docs/encoding/api-reference/sections/manifests#/Encoding/PostEncodingManifestsHlsDefault /// </summary> /// <param name="encoding">The encoding for which the manifest should be generated</param> /// <param name="output">The output to which the manifest should be written</param> /// <param name="outputPath">The path to which the manifest should be written</param> private async Task <HlsManifest> CreateDefaultHlsManifest(Models.Encoding encoding, Output output, string outputPath) { var hlsManifestDefault = new HlsManifestDefault() { EncodingId = encoding.Id, Name = "master.m3u8", Version = HlsManifestDefaultVersion.V1, Outputs = new List <EncodingOutput>() { BuildEncodingOutput(output, outputPath) } }; return(await _bitmovinApi.Encoding.Manifests.Hls.Default.CreateAsync(hlsManifestDefault)); }
/// <summary> /// Creates an DASH default manifest that automatically includes all representations configured in the encoding. /// <para /> /// API endpoints: /// https://bitmovin.com/docs/encoding/api-reference/sections/manifests#/Encoding/PostEncodingManifestsDashDefault /// </summary> /// <param name="encoding">The encoding for which the manifest should be generated</param> /// <param name="output">The output to which the manifest should be written</param> /// <param name="outputPath">The path to which the manifest should be written</param> private async Task <DashManifest> CreateDefaultDashManifest(Models.Encoding encoding, Output output, string outputPath) { var dashManifestDefault = new DashManifestDefault() { EncodingId = encoding.Id, ManifestName = "stream.mpd", Version = DashManifestDefaultVersion.V1, Outputs = new List <EncodingOutput>() { BuildEncodingOutput(output, outputPath) } }; return(await _bitmovinApi.Encoding.Manifests.Dash.Default.CreateAsync(dashManifestDefault)); }
/// <summary> /// <para>Creates a list of the previously configured filter resources and adds them to a video stream. /// The <i>position</i> property of each StreamFilter determines the order in which they are applied.</para> /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/all#/Encoding/PostEncodingEncodingsStreamsFiltersByEncodingIdAndStreamId /// </summary> /// <param name="encoding">The encoding to which the video stream belongs to</param> /// <param name="stream">The video stream to apply the filters to</param> /// <param name="filters">A list of filter resources that have been created previously</param> private Task CreateStreamFilterList(Models.Encoding encoding, Stream stream, List <Filter> filters) { var streamFilters = new List <StreamFilter>(); for (var position = 0; position < filters.Count; position++) { var streamFilter = new StreamFilter() { Id = filters.ElementAt(position).Id, Position = position }; streamFilters.Add(streamFilter); } return(_bitmovinApi.Encoding.Encodings.Streams.Filters.CreateAsync(encoding.Id, stream.Id, streamFilters)); }
/// <summary> /// Creates an HLS video playlist<para /> /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/sections/manifests#/Encoding/PostEncodingManifestsHlsStreamsByManifestId /// </summary> /// <param name="encoding">The encoding to which the manifest belongs to</param> /// <param name="hlsManifest">The manifest to which the playlist should be added</param> /// <param name="filename">The filename to be used for the playlist file</param> /// <param name="videoMuxing">The video muxing for which the playlist should be generated</param> /// <param name="segmentPath">The path containing the video segments to be referenced</param> /// <param name="audioMediaInfo">The audio media playlist containing the associated audio group id</param> private Task <StreamInfo> CreateVideoStreamPlaylist(Models.Encoding encoding, HlsManifest hlsManifest, string filename, Fmp4Muxing videoMuxing, string segmentPath, AudioMediaInfo audioMediaInfo) { var streamInfo = new StreamInfo() { Uri = filename, EncodingId = encoding.Id, StreamId = videoMuxing.Streams.ElementAt(0).StreamId, MuxingId = videoMuxing.Id, Audio = audioMediaInfo.GroupId, SegmentPath = segmentPath }; return(_bitmovinApi.Encoding.Manifests.Hls.Streams.CreateAsync(hlsManifest.Id, streamInfo)); }
/// <summary> /// Creates keyframes at specified positions of the encoded output. With SegmentCut set to true, /// the written segments will be split at keyframe positions.<para /> /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/sections/encodings#/Encoding/PostEncodingEncodingsKeyframesByEncodingId /// </summary> /// <param name="encoding">The encoding to which keyframes should be added</param> /// <param name="breakPlacements">he points in time where keyframes should be inserted /// (specified in seconds)</param> private async Task <List <Keyframe> > CreateKeyframes(Models.Encoding encoding, List <double> breakPlacements) { var keyframes = new List <Keyframe>(); foreach (var adBreak in breakPlacements) { var keyframe = new Keyframe() { Time = adBreak, SegmentCut = true }; keyframes.Add(await _bitmovinApi.Encoding.Encodings.Keyframes.CreateAsync(encoding.Id, keyframe)); } return(keyframes); }
/// <summary> /// Creates a fragmented MP4 muxing. This will split the output into continuously numbered segments /// of a given length for adaptive streaming. However, the unencrypted segments will not be written /// to a permanent storage as there's no output defined for the muxing. Instead, an output needs to /// be defined for the DRM configuration resource which will later be added to this muxing.<para/> /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/all#/Encoding/PostEncodingEncodingsMuxingsFmp4ByEncodingId /// </summary> /// <param name="encoding">The encoding to which the muxing will be added</param> /// <param name="stream">The stream to be muxed</param> private Task <Fmp4Muxing> CreateFmp4Muxing(Models.Encoding encoding, Stream stream) { var muxingStream = new MuxingStream() { StreamId = stream.Id }; var muxing = new Fmp4Muxing() { SegmentLength = 4, Streams = new List <MuxingStream>() { muxingStream } }; return(_bitmovinApi.Encoding.Encodings.Muxings.Fmp4.CreateAsync(encoding.Id, muxing)); }
/// <summary> /// Creates a stream which binds an input file to a codec configuration. /// The stream is used for muxings later on.<para /> /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/sections/encodings#/Encoding/PostEncodingEncodingsStreamsByEncodingId /// </summary> /// <param name="encoding">The encoding to add the stream onto</param> /// <param name="inputStreams">The list of inputStream resources providing the input file, to be merged</param> /// <param name="configuration">The codec configuration to be applied to the stream</param> private Task <Stream> CreateStream(Models.Encoding encoding, List <InputStream> inputStreams, CodecConfiguration configuration) { var stream = new Stream() { CodecConfigId = configuration.Id, Mode = StreamMode.STANDARD }; foreach (var inputStream in inputStreams) { stream.InputStreams.Add(new StreamInput { InputStreamId = inputStream.Id }); } return(_bitmovinApi.Encoding.Encodings.Streams.CreateAsync(encoding.Id, stream)); }
/// <summary> /// Creates a stream which binds an input file to a codec configuration. /// The stream is used for muxings later on.<para /> /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/sections/encodings#/Encoding/PostEncodingEncodingsStreamsByEncodingId /// </summary> /// <param name="encoding">The encoding to add the stream onto</param> /// <param name="input">The input that should be used</param> /// <param name="inputPath">The path to the input file</param> /// <param name="configuration">The codec configuration to be applied to the stream</param> private Task <Stream> CreateStream(Models.Encoding encoding, InputStream inputStream, CodecConfiguration configuration) { var streamInput = new StreamInput() { InputStreamId = inputStream.Id, }; var stream = new Stream() { InputStreams = new List <StreamInput>() { streamInput }, CodecConfigId = configuration.Id, Mode = StreamMode.STANDARD }; return(_bitmovinApi.Encoding.Encodings.Streams.CreateAsync(encoding.Id, stream)); }
/// <summary> /// Creates a progressive TS muxing. /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/sections/encodings#/Encoding/PostEncodingEncodingsMuxingsTsByEncodingId /// </summary> /// <param name="encoding">The encoding to add the muxing to</param> /// <param name="output">The output that should be used for the muxing to write the segments to</param> /// <param name="outputPath">The output path where the fragments will be written to</param> /// <param name="streams">A list of streams to be added to the muxing</param> /// <param name="fileName">The name of the file that will be written to the output</param> private Task CreateProgressiveTsMuxing(Models.Encoding encoding, Output output, string outputPath, List <Stream> streams, string fileName) { var muxing = new ProgressiveTsMuxing() { Outputs = new List <EncodingOutput>() { BuildEncodingOutput(output, outputPath) }, Filename = fileName }; streams.ForEach(stream => muxing.Streams.Add(new MuxingStream() { StreamId = stream.Id })); return(_bitmovinApi.Encoding.Encodings.Muxings.ProgressiveTs.CreateAsync(encoding.Id, muxing)); }
/// <summary> /// Adds an audio mix input stream to an encoding /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/sections/encodings#/Encoding/PostEncodingEncodingsStreamsByEncodingId /// </summary> /// <param name="encoding">The encoding to which the stream will be added</param> /// <param name="concatenationInputStream">The input resource providing the input file</param> /// <param name="codecConfiguration">The codec configuration to be applied to the stream</param> private Task <Stream> CreateStreamWithConcatenationInputStream(Models.Encoding encoding, ConcatenationInputStream concatenationInputStream, CodecConfiguration codecConfiguration) { var streamInput = new StreamInput() { InputStreamId = concatenationInputStream.Id }; var inputStreams = new List <StreamInput>() { streamInput }; var stream = new Stream() { InputStreams = inputStreams, CodecConfigId = codecConfiguration.Id }; return(_bitmovinApi.Encoding.Encodings.Streams.CreateAsync(encoding.Id, stream)); }
/// <summary> /// Creates a stream which binds an input file to a codec configuration. /// The stream is used for muxings later on.<para /> /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/sections/encodings#/Encoding/PostEncodingEncodingsStreamsByEncodingId /// </summary> /// <param name="encoding">The encoding to add the stream onto</param> /// <param name="input">The input that should be used</param> /// <param name="inputPath">The path to the input file</param> /// <param name="configuration">The codec configuration to be applied to the stream</param> private Task <Stream> CreateStream(Models.Encoding encoding, Input input, string inputPath, CodecConfiguration configuration) { var streamInput = new StreamInput() { InputId = input.Id, InputPath = inputPath, SelectionMode = StreamSelectionMode.AUTO }; var stream = new Stream() { InputStreams = new List <StreamInput>() { streamInput }, CodecConfigId = configuration.Id }; return(_bitmovinApi.Encoding.Encodings.Streams.CreateAsync(encoding.Id, stream)); }
/// <summary> /// Creates an HLS audio media playlist<para /> /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/sections/manifests#/Encoding/PostEncodingManifestsHlsMediaAudioByManifestId /// </summary> /// <param name="encoding">The encoding to which the manifest belongs to</param> /// <param name="hlsManifest">The manifest to which the playlist should be added</param> /// <param name="audioMuxing">The audio muxing for which the playlist should be generated</param> /// <param name="segmentPath">The path containing the audio segments to be referenced by the playlist</param> private Task <AudioMediaInfo> CreateAudioMediaPlaylist(Models.Encoding encoding, HlsManifest hlsManifest, Fmp4Muxing audioMuxing, string segmentPath) { var audioMediaInfo = new AudioMediaInfo() { Name = "audio.m3u8", Uri = "audio.m3u8", GroupId = "audio", EncodingId = encoding.Id, StreamId = audioMuxing.Streams[0].StreamId, MuxingId = audioMuxing.Id, Language = "en", AssocLanguage = "en", Autoselect = false, IsDefault = false, Forced = false, SegmentPath = segmentPath }; return(_bitmovinApi.Encoding.Manifests.Hls.Media.Audio.CreateAsync(hlsManifest.Id, audioMediaInfo)); }
/// <summary> /// Starts the actual encoding process and periodically polls its status until it reaches a final state<para /> /// /// API endpoints: /// https://bitmovin.com/docs/encoding/api-reference/all#/Encoding/PostEncodingEncodingsStartByEncodingId /// <br /> /// https://bitmovin.com/docs/encoding/api-reference/sections/encodings#/Encoding/GetEncodingEncodingsStatusByEncodingId /// <para /> /// Please note that you can also use our webhooks API instead of polling the status. For more /// information consult the API spec: /// https://bitmovin.com/docs/encoding/api-reference/sections/notifications-webhooks /// </summary> /// <param name="encoding">The encoding to be started</param> /// <exception cref="System.SystemException"></exception> private async Task ExecuteEncoding(Models.Encoding encoding) { await _bitmovinApi.Encoding.Encodings.StartAsync(encoding.Id); ServiceTaskStatus serviceTaskStatus; do { await Task.Delay(5000); serviceTaskStatus = await _bitmovinApi.Encoding.Encodings.StatusAsync(encoding.Id); Console.WriteLine($"Encoding status is {serviceTaskStatus.Status} (progress: {serviceTaskStatus.Progress} %)"); } while (serviceTaskStatus.Status != Status.FINISHED && serviceTaskStatus.Status != Status.ERROR); if (serviceTaskStatus.Status == Status.ERROR) { LogTaskErrors(serviceTaskStatus); throw new SystemException("Encoding failed"); } Console.WriteLine("Encoding finished successfully"); }
/// <summary> /// Creates a fragmented MP4 muxing. This will generate segments with a given segment length for /// adaptive streaming.<para /> /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/all#/Encoding/PostEncodingEncodingsMuxingsFmp4ByEncodingId /// </summary> /// <param name="encoding">The encoding where to add the muxing to</param> /// <param name="output">The output that should be used for the muxing to write the segments to</param> /// <param name="outputPath">The output path where the fragmented segments will be written to</param> /// <param name="stream">The stream to be muxed</param> private Task <Fmp4Muxing> CreateFmp4Muxing(Models.Encoding encoding, Output output, string outputPath, Stream stream) { var muxingStream = new MuxingStream() { StreamId = stream.Id }; var muxing = new Fmp4Muxing() { SegmentLength = 4, Outputs = new List <EncodingOutput>() { BuildEncodingOutput(output, outputPath) }, Streams = new List <MuxingStream>() { muxingStream } }; return(_bitmovinApi.Encoding.Encodings.Muxings.Fmp4.CreateAsync(encoding.Id, muxing)); }
/// <summary> /// Creates a MP4 muxing.<para /> /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/sections/encodings#/Encoding/PostEncodingEncodingsMuxingsMp4ByEncodingId /// </summary> /// <param name="encoding">The encoding to add the muxing to</param> /// <param name="output">The output that should be used for the muxing to write the segments to</param> /// <param name="outputPath">The output path where the fragments will be written to</param> /// <param name="streams">A list of streams to be added to the muxing</param> /// <param name="fileName">The name of the file that will be written to the output</param> private Task CreateMp4Muxing(Models.Encoding encoding, Output output, string outputPath, List <Stream> streams, string fileName) { var muxing = new Mp4Muxing() { Outputs = new List <EncodingOutput>() { BuildEncodingOutput(output, outputPath) }, Filename = fileName }; foreach (var stream in streams) { var muxingSteam = new MuxingStream() { StreamId = stream.Id }; muxing.Streams.Add(muxingSteam); } return(_bitmovinApi.Encoding.Encodings.Muxings.Mp4.CreateAsync(encoding.Id, muxing)); }
/// <summary> /// Creates an audio mix input stream.<para /> /// /// The output resolution is defined by setting the height to 1080 pixels. Width will be determined /// automatically to maintain the aspect ratio of your input video.<para /> /// /// To keep things simple, we use a quality-optimized VoD preset configuration, which will apply proven settings /// for the codec. See "How to optimize your H264 codec configuration for different use-cases" /// (https://bitmovin.com/docs/encoding/tutorials/how-to-optimize-your-h264-codec-configuration-for-different-use-cases) /// for alternative presets.<para /> /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/all#/Encoding/PostEncodingEncodingsInputStreamsAudioMixByEncodingId /// </summary> /// <param name="encoding">The encoding to be started</param> /// <param name="audioMixInputStream">The audio mix input stream to be created.</param> /// <param name="audioMixChannels">The audio mix input stream channels to be added.</param> private Task <AudioMixInputStream> CreateAudioMixInputStream(Models.Encoding encoding, AudioMixInputStream audioMixInputStream, List <AudioMixInputStreamChannel> audioMixChannels) { audioMixInputStream.AudioMixChannels = audioMixChannels; return(_bitmovinApi.Encoding.Encodings.InputStreams.AudioMix.CreateAsync(encoding.Id, audioMixInputStream)); }
/// <summary> /// Create Encoding /// </summary> /// <param name="encoding">The Encoding to be created</param> public async Task <Models.Encoding> CreateAsync(Models.Encoding encoding) { return(await _apiClient.CreateAsync(encoding)); }
/// <summary> /// Creates a collection of audio mix channels <para /> /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/sections/encodings#/Encoding/PostEncodingEncodingsInputStreamsIngestByEncodingId /// </summary> /// <param name="encoding">The encoding to which the stream will be added</param> /// <param name="input"> The input resource providing the input file</param> /// <param name="inputPath"> The path to the input file</param> /// <param name="mappingConfigs">The configuration of the mapping of source channels to output channels</param> private async Task <List <AudioMixInputStreamChannel> > CreateAudioMixInputStreamChannels(Models.Encoding encoding, Input input, String inputPath, List <ChannelMappingConfiguration> mappingConfigs) { var audioMixInputStream = new List <AudioMixInputStreamChannel>(); foreach (var mappingConfig in mappingConfigs) { var audioIngestInputStream = await CreateIngestInputStreamForAudioTrack(encoding, input, inputPath, mappingConfig.SourceChannelNumber); var sourceChannel = new AudioMixInputStreamSourceChannel() { Type = AudioMixSourceChannelType.CHANNEL_NUMBER, ChannelNumber = 0 }; var outputChannel = new AudioMixInputStreamChannel() { InputStreamId = audioIngestInputStream.Id, OutputChannelType = mappingConfig.OutputChannelType, SourceChannels = new List <AudioMixInputStreamSourceChannel>() { sourceChannel } }; audioMixInputStream.Add(outputChannel); } return(audioMixInputStream); }
/// <summary> /// Creates a TimeBasedTrimmingInputStream and adds it to an encoding. /// The TimeBasedTrimmingInputStream is used to define a section of an IngestInputStream using an offset and a duration /// expressed in seconds. <para /> /// /// API endpoint: /// https://bitmovin.com/docs/encoding/api-reference/sections/encodings#/Encoding/PostEncodingEncodingsInputStreamsTrimmingTimeBasedByEncodingId /// </summary> /// <param name="encoding">The encoding to add the stream onto</param> /// <param name="ingestInputStream">The IngestInputStream instance created from the input file</param> /// <param name="offset">Defines the offset in seconds at which the encoding should start, beginning at 0.</param> /// <param name="duration">Defines how many seconds of the input will be encoded.</param> private Task <TimeBasedTrimmingInputStream> CreateTimeBasedTrimmingInputStream(Models.Encoding encoding, IngestInputStream ingestInputStream, double offset, double duration) { var timeBasedTrimmingInputStream = new TimeBasedTrimmingInputStream() { InputStreamId = ingestInputStream.Id, Offset = offset, Duration = duration }; return(_bitmovinApi.Encoding.Encodings.InputStreams.Trimming.TimeBased.CreateAsync(encoding.Id, timeBasedTrimmingInputStream)); }