/// <summary> /// Builds an audio header. /// </summary> /// <param name="profile">A <see cref="DeviceProfile"/>.</param> /// <param name="container">The container.</param> /// <param name="audioCodec">The audio codec.</param> /// <param name="audioBitrate">Optional. The audio bitrate.</param> /// <param name="audioSampleRate">Optional. The sample audio rate.</param> /// <param name="audioChannels">Optional. The number of audio channels.</param> /// <param name="audioBitDepth">Optional. The audio bit depth.</param> /// <param name="isDirectStream">True if being accessed by audio stream.</param> /// <param name="runtimeTicks">Optional. The runtime ticks.</param> /// <param name="transcodeSeekInfo">An instance of <see cref="TranscodeSeekInfo"/>.</param> /// <returns>A string representation.</returns> public static string BuildAudioHeader( DeviceProfile profile, string container, string?audioCodec, int?audioBitrate, int?audioSampleRate, int?audioChannels, int?audioBitDepth, bool isDirectStream, long?runtimeTicks, TranscodeSeekInfo transcodeSeekInfo) { if (profile == null) { throw new ArgumentNullException(nameof(profile)); } // first bit means Time based seek supported, second byte range seek supported (not sure about the order now), so 01 = only byte seek, 10 = time based, 11 = both, 00 = none string orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetOrgOpValue(runtimeTicks > 0, isDirectStream, transcodeSeekInfo); // 0 = native, 1 = transcoded string orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1"; const DlnaFlags FlagValue = DlnaFlags.StreamingTransferMode | DlnaFlags.BackgroundTransferMode | DlnaFlags.InteractiveTransferMode | DlnaFlags.DlnaV15; // if (isDirectStream) // { // flagValue = flagValue | DlnaFlags.ByteBasedSeek; // } // else if (runtimeTicks.HasValue) // { // flagValue = flagValue | DlnaFlags.TimeBasedSeek; // } string dlnaflags = string.Format( CultureInfo.InvariantCulture, ";DLNA.ORG_FLAGS={0}", DlnaMaps.FlagsToString(FlagValue)); var mediaProfile = profile.GetAudioMediaProfile( container, audioCodec, audioChannels, audioBitrate, audioSampleRate, audioBitDepth); var orgPn = mediaProfile?.OrgPn; if (string.IsNullOrEmpty(orgPn)) { orgPn = GetAudioOrgPnValue(container, audioBitrate, audioSampleRate, audioChannels); } if (string.IsNullOrEmpty(orgPn)) { return(orgOp.TrimStart(';') + orgCi + dlnaflags); } return("DLNA.ORG_PN=" + orgPn + orgOp + orgCi + dlnaflags); }
/// <summary> /// Builds a video header. /// </summary> /// <param name="profile">A <see cref="DeviceProfile"/>.</param> /// <param name="container">The container.</param> /// <param name="videoCodec">The video codec.</param> /// <param name="audioCodec">The audio codec.</param> /// <param name="width">Optional. The width.</param> /// <param name="height">Optional. The height.</param> /// <param name="bitDepth">Optional. The bit depth.</param> /// <param name="videoBitrate">Optional. The video bitrate.</param> /// <param name="timestamp">Optional. A <see cref="TransportStreamTimestamp"/>.</param> /// <param name="isDirectStream">True if the stream is playable by directStream.</param> /// <param name="runtimeTicks">Optional. Runtime ticks.</param> /// <param name="videoProfile">The video profile.</param> /// <param name="videoLevel">Optional. The video level.</param> /// <param name="videoFramerate">Optional. The video framerate.</param> /// <param name="packetLength">Optional. The packet length.</param> /// <param name="transcodeSeekInfo">The <see cref="TranscodeSeekInfo"/>.</param> /// <param name="isAnamorphic">Optional. True, if anamorphic.</param> /// <param name="isInterlaced">Optional. True, if interlaced.</param> /// <param name="refFrames">Optional. The number of reference frames.</param> /// <param name="numVideoStreams">Optional. The number of video streams.</param> /// <param name="numAudioStreams">Optional. The number of audio streams.</param> /// <param name="videoCodecTag">The video codec tag.</param> /// <param name="isAvc">True is AVC.</param> /// <returns>A list containing the video information.</returns> public static List <string> BuildVideoHeader( DeviceProfile profile, string container, string?videoCodec, string?audioCodec, int?width, int?height, int?bitDepth, int?videoBitrate, TransportStreamTimestamp timestamp, bool isDirectStream, long?runtimeTicks, string?videoProfile, double?videoLevel, float?videoFramerate, int?packetLength, TranscodeSeekInfo transcodeSeekInfo, bool?isAnamorphic, bool?isInterlaced, int?refFrames, int?numVideoStreams, int?numAudioStreams, string?videoCodecTag, bool?isAvc) { if (profile == null) { throw new ArgumentNullException(nameof(profile)); } // first bit means Time based seek supported, second byte range seek supported (not sure about the order now), so 01 = only byte seek, 10 = time based, 11 = both, 00 = none string orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetOrgOpValue(runtimeTicks > 0, isDirectStream, transcodeSeekInfo); // 0 = native, 1 = transcoded string orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1"; var flagValue = DlnaFlags.StreamingTransferMode | DlnaFlags.BackgroundTransferMode | DlnaFlags.InteractiveTransferMode | DlnaFlags.DlnaV15; if (isDirectStream) { flagValue |= DlnaFlags.ByteBasedSeek; } else if (runtimeTicks.HasValue) { flagValue |= DlnaFlags.TimeBasedSeek; } string dlnaflags = string.Format(CultureInfo.InvariantCulture, ";DLNA.ORG_FLAGS={0}", DlnaMaps.FlagsToString(flagValue)); var mediaProfile = profile.GetVideoMediaProfile( container, audioCodec, videoCodec, width, height, bitDepth, videoBitrate, videoProfile, videoLevel, videoFramerate, packetLength, timestamp, isAnamorphic, isInterlaced, refFrames, numVideoStreams, numAudioStreams, videoCodecTag, isAvc); var orgPnValues = new List <string>(); if (mediaProfile != null && !string.IsNullOrEmpty(mediaProfile.OrgPn)) { orgPnValues.AddRange(mediaProfile.OrgPn.Split(',', StringSplitOptions.RemoveEmptyEntries)); } else { foreach (var s in GetVideoOrgPnValue(container, videoCodec, audioCodec, width, height, timestamp)) { orgPnValues.Add(s.ToString()); break; } } var contentFeatureList = new List <string>(); foreach (string orgPn in orgPnValues) { if (string.IsNullOrEmpty(orgPn)) { contentFeatureList.Add(orgOp.TrimStart(';') + orgCi + dlnaflags); } else { contentFeatureList.Add("DLNA.ORG_PN=" + orgPn + orgCi + dlnaflags); } } if (orgPnValues.Count == 0) { contentFeatureList.Add(orgOp.TrimStart(';') + orgCi + dlnaflags); } return(contentFeatureList); }