using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace MediaBrowser.Dlna.PlayTo
{
class StreamHelper
{
///
/// Gets the dlna headers.
///
/// The item.
///
internal static string GetDlnaHeaders(PlaylistItem item)
{
var orgOp = item.Transcode ? ";DLNA.ORG_OP=00" : ";DLNA.ORG_OP=01";
var orgCi = item.Transcode ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1";
const string dlnaflags = ";DLNA.ORG_FLAGS=01500000000000000000000000000000";
var contentFeatures = string.Empty;
if (string.Equals(item.FileFormat, "mp3", StringComparison.OrdinalIgnoreCase))
{
contentFeatures = "DLNA.ORG_PN=MP3";
}
else if (string.Equals(item.FileFormat, "wma", StringComparison.OrdinalIgnoreCase))
{
contentFeatures = "DLNA.ORG_PN=WMABASE";
}
else if (string.Equals(item.FileFormat, "avi", StringComparison.OrdinalIgnoreCase))
{
contentFeatures = "DLNA.ORG_PN=AVI";
}
else if (string.Equals(item.FileFormat, "mkv", StringComparison.OrdinalIgnoreCase))
{
contentFeatures = "DLNA.ORG_PN=MATROSKA";
}
else if (string.Equals(item.FileFormat, "mp4", StringComparison.OrdinalIgnoreCase))
{
contentFeatures = "DLNA.ORG_PN=AVC_MP4_MP_HD_720p_AAC";
}
else if (string.Equals(item.FileFormat, "mpeg", StringComparison.OrdinalIgnoreCase))
{
contentFeatures = "DLNA.ORG_PN=MPEG_PS_PAL";
}
else if (string.Equals(item.FileFormat, "ts", StringComparison.OrdinalIgnoreCase))
{
contentFeatures = "DLNA.ORG_PN=MPEG_PS_PAL";
}
else if (item.IsVideo)
{
//Default to AVI for video
contentFeatures = "DLNA.ORG_PN=AVI";
}
else
{
//Default to MP3 for audio
contentFeatures = "DLNA.ORG_PN=MP3";
}
return (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';');
}
#region Audio
///
/// Gets the audio URL.
///
/// The item.
/// The server address.
/// System.String.
internal static string GetAudioUrl(PlaylistItem item, string serverAddress)
{
if (!item.Transcode)
return string.Format("{0}/audio/{1}/stream.{2}?Static=True", serverAddress, item.ItemId, item.FileFormat);
return string.Format("{0}/audio/{1}/stream.mp3?AudioCodec=Mp3", serverAddress, item.ItemId);
}
#endregion
#region Video
///
/// Gets the video URL.
///
/// The device properties.
/// The item.
/// The streams.
/// The server address.
/// The url to send to the device
internal static string GetVideoUrl(DeviceProperties deviceProperties, PlaylistItem item, List streams, string serverAddress)
{
if (!item.Transcode)
return string.Format("{0}/Videos/{1}/stream.{2}?Static=True", serverAddress, item.ItemId, item.FileFormat);
var videostream = streams.Where(m => m.Type == MediaStreamType.Video).OrderBy(m => m.IsDefault).FirstOrDefault();
var audiostream = streams.Where(m => m.Type == MediaStreamType.Audio).OrderBy(m => m.IsDefault).FirstOrDefault();
var videoCodec = GetVideoCodec(videostream);
var audioCodec = GetAudioCodec(audiostream);
int? videoBitrate = null;
int? audioBitrate = null;
int? audioChannels = null;
if (videoCodec != VideoCodecs.Copy)
videoBitrate = 2000000;
if (audioCodec != AudioCodecs.Copy)
{
audioBitrate = 128000;
audioChannels = 2;
}
string dlnaCommand = BuildDlnaUrl(deviceProperties.UUID, videoCodec, audioCodec, null, null, videoBitrate, audioChannels, audioBitrate, item.StartPositionTicks, "baseline", "3");
return string.Format("{0}/Videos/{1}/stream.{2}?{3}", serverAddress, item.ItemId, item.FileFormat, dlnaCommand);
}
///
/// Gets the video codec.
///
/// The video stream.
///
private static VideoCodecs GetVideoCodec(MediaStream videoStream)
{
switch (videoStream.Codec.ToLower())
{
case "h264":
case "mpeg4":
return VideoCodecs.Copy;
}
return VideoCodecs.H264;
}
///
/// Gets the audio codec.
///
/// The audio stream.
///
private static AudioCodecs GetAudioCodec(MediaStream audioStream)
{
if (audioStream != null)
{
switch (audioStream.Codec.ToLower())
{
case "aac":
case "mp3":
case "wma":
return AudioCodecs.Copy;
}
}
return AudioCodecs.Aac;
}
///
/// Builds the dlna URL.
///
private static string BuildDlnaUrl(string deviceID, VideoCodecs? videoCodec, AudioCodecs? audioCodec, int? subtitleIndex, int? audiostreamIndex, int? videoBitrate, int? audiochannels, int? audioBitrate, long? startPositionTicks, string profile, string videoLevel)
{
var usCulture = new CultureInfo("en-US");
var dlnaparam = string.Format("Params={0};", deviceID);
dlnaparam += videoCodec.HasValue ? videoCodec.Value + ";" : ";";
dlnaparam += audioCodec.HasValue ? audioCodec.Value + ";" : ";";
dlnaparam += audiostreamIndex.HasValue ? audiostreamIndex.Value.ToString(usCulture) + ";" : ";";
dlnaparam += subtitleIndex.HasValue ? subtitleIndex.Value.ToString(usCulture) + ";" : ";";
dlnaparam += videoBitrate.HasValue ? videoBitrate.Value.ToString(usCulture) + ";" : ";";
dlnaparam += audioBitrate.HasValue ? audioBitrate.Value.ToString(usCulture) + ";" : ";";
dlnaparam += audiochannels.HasValue ? audiochannels.Value.ToString(usCulture) + ";" : ";";
dlnaparam += startPositionTicks.HasValue ? startPositionTicks.Value.ToString(usCulture) + ";" : ";";
dlnaparam += profile + ";";
dlnaparam += videoLevel + ";";
return dlnaparam;
}
#endregion
}
}