123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using MediaBrowser.Model.Entities;
- using MediaBrowser.Model.MediaInfo;
- namespace MediaBrowser.Model.Dlna
- {
- public class ContentFeatureBuilder
- {
- private readonly DeviceProfile _profile;
- public ContentFeatureBuilder(DeviceProfile profile)
- {
- _profile = profile;
- }
- public string BuildImageHeader(string container,
- int? width,
- int? height)
- {
- var orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetImageOrgOpValue();
- // 0 = native, 1 = transcoded
- const string orgCi = ";DLNA.ORG_CI=0";
- var flagValue = DlnaFlags.StreamingTransferMode |
- DlnaFlags.BackgroundTransferMode |
- DlnaFlags.DlnaV15;
- var dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}",
- FlagsToString(flagValue));
- var mediaProfile = _profile.GetImageMediaProfile(container,
- width,
- height);
- var orgPn = mediaProfile == null ? null : mediaProfile.OrgPn;
- if (string.IsNullOrEmpty(orgPn))
- {
- orgPn = GetImageOrgPnValue(container, width, height);
- }
- var contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn;
- return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';');
- }
- public string BuildAudioHeader(string container,
- string audioCodec,
- int? audioBitrate,
- int? audioSampleRate,
- int? audioChannels,
- bool isDirectStream,
- long? runtimeTicks,
- TranscodeSeekInfo transcodeSeekInfo)
- {
- // 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
- var orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetOrgOpValue(runtimeTicks.HasValue, isDirectStream, transcodeSeekInfo);
- // 0 = native, 1 = transcoded
- var orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1";
- var flagValue = DlnaFlags.StreamingTransferMode |
- DlnaFlags.BackgroundTransferMode |
- DlnaFlags.DlnaV15;
- if (isDirectStream)
- {
- //flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_BYTE_BASED_SEEK;
- }
- else if (runtimeTicks.HasValue)
- {
- //flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_TIME_BASED_SEEK;
- }
- var dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}",
- FlagsToString(flagValue));
- var mediaProfile = _profile.GetAudioMediaProfile(container,
- audioCodec,
- audioChannels,
- audioBitrate);
- var orgPn = mediaProfile == null ? null : mediaProfile.OrgPn;
- if (string.IsNullOrEmpty(orgPn))
- {
- orgPn = GetAudioOrgPnValue(container, audioBitrate, audioSampleRate, audioChannels);
- }
- var contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn;
- return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';');
- }
- private static string FlagsToString(DlnaFlags flags)
- {
- //return Enum.Format(typeof(DlnaFlags), flags, "x");
- return string.Format("{0:X8}{1:D24}", (ulong)flags, 0);
- }
- public string BuildVideoHeader(string container,
- string videoCodec,
- string audioCodec,
- int? width,
- int? height,
- int? bitDepth,
- int? videoBitrate,
- int? audioChannels,
- int? audioBitrate,
- TransportStreamTimestamp timestamp,
- bool isDirectStream,
- long? runtimeTicks,
- string videoProfile,
- double? videoLevel,
- double? videoFramerate,
- int? packetLength,
- TranscodeSeekInfo transcodeSeekInfo)
- {
- // 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
- var orgOp = ";DLNA.ORG_OP=" + DlnaMaps.GetOrgOpValue(runtimeTicks.HasValue, isDirectStream, transcodeSeekInfo);
- // 0 = native, 1 = transcoded
- var orgCi = isDirectStream ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1";
- var flagValue = DlnaFlags.StreamingTransferMode |
- DlnaFlags.BackgroundTransferMode |
- DlnaFlags.DlnaV15;
- if (isDirectStream)
- {
- //flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_BYTE_BASED_SEEK;
- }
- else if (runtimeTicks.HasValue)
- {
- //flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_TIME_BASED_SEEK;
- }
- var dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}000000000000000000000000",
- Enum.Format(typeof(DlnaFlags), flagValue, "x"));
- var mediaProfile = _profile.GetVideoMediaProfile(container,
- audioCodec,
- videoCodec,
- audioBitrate,
- audioChannels,
- width,
- height,
- bitDepth,
- videoBitrate,
- videoProfile,
- videoLevel,
- videoFramerate,
- packetLength,
- timestamp);
- var orgPn = mediaProfile == null ? null : mediaProfile.OrgPn;
- if (string.IsNullOrEmpty(orgPn))
- {
- orgPn = GetVideoOrgPnValue(container, videoCodec, audioCodec, width, height, timestamp)
- .FirstOrDefault();
- // TODO: Support multiple values and return multiple headers?
- orgPn = (orgPn ?? string.Empty).Split(',').FirstOrDefault();
- }
- var contentFeatures = string.IsNullOrEmpty(orgPn) ? string.Empty : "DLNA.ORG_PN=" + orgPn;
- return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';');
- }
- private string GetImageOrgPnValue(string container, int? width, int? height)
- {
- var format = new MediaFormatProfileResolver()
- .ResolveImageFormat(container,
- width,
- height);
- return format.HasValue ? format.Value.ToString() : null;
- }
- private string GetAudioOrgPnValue(string container, int? audioBitrate, int? audioSampleRate, int? audioChannels)
- {
- var format = new MediaFormatProfileResolver()
- .ResolveAudioFormat(container,
- audioBitrate,
- audioSampleRate,
- audioChannels);
- return format.HasValue ? format.Value.ToString() : null;
- }
- private IEnumerable<string> GetVideoOrgPnValue(string container, string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestamp)
- {
- return new MediaFormatProfileResolver()
- .ResolveVideoFormat(container,
- videoCodec,
- audioCodec,
- width,
- height,
- timestamp)
- .Select(i => i.ToString());
- }
- }
- }
|