diff options
Diffstat (limited to 'MediaBrowser.Api/Playback/Dash/ManifestBuilder.cs')
| -rw-r--r-- | MediaBrowser.Api/Playback/Dash/ManifestBuilder.cs | 224 |
1 files changed, 0 insertions, 224 deletions
diff --git a/MediaBrowser.Api/Playback/Dash/ManifestBuilder.cs b/MediaBrowser.Api/Playback/Dash/ManifestBuilder.cs deleted file mode 100644 index 35e252a19..000000000 --- a/MediaBrowser.Api/Playback/Dash/ManifestBuilder.cs +++ /dev/null @@ -1,224 +0,0 @@ -using System; -using System.Globalization; -using System.Security; -using System.Text; - -namespace MediaBrowser.Api.Playback.Dash -{ - public class ManifestBuilder - { - protected readonly CultureInfo UsCulture = new CultureInfo("en-US"); - - public string GetManifestText(StreamState state, string playlistUrl) - { - var builder = new StringBuilder(); - - var time = TimeSpan.FromTicks(state.RunTimeTicks.Value); - - var duration = "PT" + time.Hours.ToString("00", UsCulture) + "H" + time.Minutes.ToString("00", UsCulture) + "M" + time.Seconds.ToString("00", UsCulture) + ".00S"; - - builder.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); - - builder.AppendFormat( - "<MPD xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:mpeg:dash:schema:mpd:2011\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xsi:schemaLocation=\"urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd\" profiles=\"urn:mpeg:dash:profile:isoff-live:2011\" type=\"static\" mediaPresentationDuration=\"{0}\" minBufferTime=\"PT5.0S\">", - duration); - - builder.Append("<ProgramInformation>"); - builder.Append("</ProgramInformation>"); - - builder.Append("<Period start=\"PT0S\">"); - builder.Append(GetVideoAdaptationSet(state, playlistUrl)); - builder.Append(GetAudioAdaptationSet(state, playlistUrl)); - builder.Append("</Period>"); - - builder.Append("</MPD>"); - - return builder.ToString(); - } - - private string GetVideoAdaptationSet(StreamState state, string playlistUrl) - { - var builder = new StringBuilder(); - - builder.Append("<AdaptationSet id=\"video\" segmentAlignment=\"true\" bitstreamSwitching=\"true\">"); - builder.Append(GetVideoRepresentationOpenElement(state)); - - AppendSegmentList(state, builder, "0", playlistUrl); - - builder.Append("</Representation>"); - builder.Append("</AdaptationSet>"); - - return builder.ToString(); - } - - private string GetAudioAdaptationSet(StreamState state, string playlistUrl) - { - var builder = new StringBuilder(); - - builder.Append("<AdaptationSet id=\"audio\" segmentAlignment=\"true\" bitstreamSwitching=\"true\">"); - builder.Append(GetAudioRepresentationOpenElement(state)); - - builder.Append("<AudioChannelConfiguration schemeIdUri=\"urn:mpeg:dash:23003:3:audio_channel_configuration:2011\" value=\"6\" />"); - - AppendSegmentList(state, builder, "1", playlistUrl); - - builder.Append("</Representation>"); - builder.Append("</AdaptationSet>"); - - return builder.ToString(); - } - - private string GetVideoRepresentationOpenElement(StreamState state) - { - var codecs = GetVideoCodecDescriptor(state); - - var mime = "video/mp4"; - - var xml = "<Representation id=\"0\" mimeType=\"" + mime + "\" codecs=\"" + codecs + "\""; - - if (state.OutputWidth.HasValue) - { - xml += " width=\"" + state.OutputWidth.Value.ToString(UsCulture) + "\""; - } - if (state.OutputHeight.HasValue) - { - xml += " height=\"" + state.OutputHeight.Value.ToString(UsCulture) + "\""; - } - if (state.OutputVideoBitrate.HasValue) - { - xml += " bandwidth=\"" + state.OutputVideoBitrate.Value.ToString(UsCulture) + "\""; - } - - xml += ">"; - - return xml; - } - - private string GetAudioRepresentationOpenElement(StreamState state) - { - var codecs = GetAudioCodecDescriptor(state); - - var mime = "audio/mp4"; - - var xml = "<Representation id=\"1\" mimeType=\"" + mime + "\" codecs=\"" + codecs + "\""; - - if (state.OutputAudioSampleRate.HasValue) - { - xml += " audioSamplingRate=\"" + state.OutputAudioSampleRate.Value.ToString(UsCulture) + "\""; - } - if (state.OutputAudioBitrate.HasValue) - { - xml += " bandwidth=\"" + state.OutputAudioBitrate.Value.ToString(UsCulture) + "\""; - } - - xml += ">"; - - return xml; - } - - private string GetVideoCodecDescriptor(StreamState state) - { - // https://developer.apple.com/library/ios/documentation/networkinginternet/conceptual/streamingmediaguide/FrequentlyAskedQuestions/FrequentlyAskedQuestions.html - // http://www.chipwreck.de/blog/2010/02/25/html-5-video-tag-and-attributes/ - - var level = state.TargetVideoLevel ?? 0; - var profile = state.TargetVideoProfile ?? string.Empty; - - if (profile.IndexOf("high", StringComparison.OrdinalIgnoreCase) != -1) - { - if (level >= 4.1) - { - return "avc1.640028"; - } - - if (level >= 4) - { - return "avc1.640028"; - } - - return "avc1.64001f"; - } - - if (profile.IndexOf("main", StringComparison.OrdinalIgnoreCase) != -1) - { - if (level >= 4) - { - return "avc1.4d0028"; - } - - if (level >= 3.1) - { - return "avc1.4d001f"; - } - - return "avc1.4d001e"; - } - - if (level >= 3.1) - { - return "avc1.42001f"; - } - - return "avc1.42E01E"; - } - - private string GetAudioCodecDescriptor(StreamState state) - { - // https://developer.apple.com/library/ios/documentation/networkinginternet/conceptual/streamingmediaguide/FrequentlyAskedQuestions/FrequentlyAskedQuestions.html - - if (string.Equals(state.OutputAudioCodec, "mp3", StringComparison.OrdinalIgnoreCase)) - { - return "mp4a.40.34"; - } - - // AAC 5ch - if (state.OutputAudioChannels.HasValue && state.OutputAudioChannels.Value >= 5) - { - return "mp4a.40.5"; - } - - // AAC 2ch - return "mp4a.40.2"; - } - - private void AppendSegmentList(StreamState state, StringBuilder builder, string type, string playlistUrl) - { - var extension = ".m4s"; - - var seconds = TimeSpan.FromTicks(state.RunTimeTicks ?? 0).TotalSeconds; - - var queryStringIndex = playlistUrl.IndexOf('?'); - var queryString = queryStringIndex == -1 ? string.Empty : playlistUrl.Substring(queryStringIndex); - - var index = 0; - var duration = 1000000 * state.SegmentLength; - builder.AppendFormat("<SegmentList timescale=\"1000000\" duration=\"{0}\" startNumber=\"1\">", duration.ToString(CultureInfo.InvariantCulture)); - - while (seconds > 0) - { - var filename = index == 0 - ? "init" - : (index - 1).ToString(UsCulture); - - var segmentUrl = string.Format("dash/{3}/{0}{1}{2}", - filename, - extension, - SecurityElement.Escape(queryString), - type); - - if (index == 0) - { - builder.AppendFormat("<Initialization sourceURL=\"{0}\"/>", segmentUrl); - } - else - { - builder.AppendFormat("<SegmentURL media=\"{0}\"/>", segmentUrl); - } - - seconds -= state.SegmentLength; - index++; - } - builder.Append("</SegmentList>"); - } - } -} |
