Browse Source

Added VideoInfo to DTOBaseItem

LukePulverenti Luke Pulverenti luke pulverenti 13 years ago
parent
commit
f2de85b5d9

+ 16 - 0
MediaBrowser.Api/ApiService.cs

@@ -117,6 +117,22 @@ namespace MediaBrowser.Api
                 };
             }
 
+            Video video = item as Video;
+
+            if (video != null)
+            {
+                dto.VideoInfo = new VideoInfo()
+                {
+                    Height = video.Height,
+                    Width = video.Width,
+                    Codec = video.Codec,
+                    VideoType = video.VideoType,
+                    AudioStreams = video.AudioStreams,
+                    Subtitles = video.Subtitles,
+                    ScanType = video.ScanType
+                };
+            }
+
             return dto;
         }
 

+ 20 - 15
MediaBrowser.ApiInteraction/ApiClient.cs

@@ -154,7 +154,7 @@ namespace MediaBrowser.ApiInteraction
         /// </summary>
         public Task<Stream> GetImageStreamAsync(string url)
         {
-            return HttpClient.GetStreamAsync(url);
+            return GetStreamAsync(url);
         }
 
         /// <summary>
@@ -169,7 +169,7 @@ namespace MediaBrowser.ApiInteraction
                 url += "&id=" + id.ToString();
             }
 
-            using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
+            using (Stream stream = await GetStreamAsync(url).ConfigureAwait(false))
             {
                 return JsonSerializer.DeserializeFromStream<DTOBaseItem>(stream);
             }
@@ -182,7 +182,7 @@ namespace MediaBrowser.ApiInteraction
         {
             string url = ApiUrl + "/users";
 
-            using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
+            using (Stream stream = await GetStreamAsync(url).ConfigureAwait(false))
             {
                 return JsonSerializer.DeserializeFromStream<IEnumerable<User>>(stream);
             }
@@ -195,7 +195,7 @@ namespace MediaBrowser.ApiInteraction
         {
             string url = ApiUrl + "/genres?userId=" + userId.ToString();
 
-            using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
+            using (Stream stream = await GetStreamAsync(url).ConfigureAwait(false))
             {
                 return JsonSerializer.DeserializeFromStream<IEnumerable<IBNItem<Genre>>>(stream);
             }
@@ -208,7 +208,7 @@ namespace MediaBrowser.ApiInteraction
         {
             string url = ApiUrl + "/years?userId=" + userId.ToString();
 
-            using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
+            using (Stream stream = await GetStreamAsync(url).ConfigureAwait(false))
             {
                 return JsonSerializer.DeserializeFromStream<IEnumerable<IBNItem<Year>>>(stream);
             }
@@ -221,7 +221,7 @@ namespace MediaBrowser.ApiInteraction
         {
             string url = ApiUrl + "/itemlist?listtype=itemswithyear&userId=" + userId.ToString() + "&name=" + name;
 
-            using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
+            using (Stream stream = await GetStreamAsync(url).ConfigureAwait(false))
             {
                 return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
             }
@@ -234,7 +234,7 @@ namespace MediaBrowser.ApiInteraction
         {
             string url = ApiUrl + "/itemlist?listtype=itemswithgenre&userId=" + userId.ToString() + "&name=" + name;
 
-            using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
+            using (Stream stream = await GetStreamAsync(url).ConfigureAwait(false))
             {
                 return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
             }
@@ -247,7 +247,7 @@ namespace MediaBrowser.ApiInteraction
         {
             string url = ApiUrl + "/itemlist?listtype=itemswithperson&userId=" + userId.ToString() + "&name=" + name;
 
-            using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
+            using (Stream stream = await GetStreamAsync(url).ConfigureAwait(false))
             {
                 return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
             }
@@ -262,7 +262,7 @@ namespace MediaBrowser.ApiInteraction
 
             url += "&persontype=" + personType;
 
-            using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
+            using (Stream stream = await GetStreamAsync(url).ConfigureAwait(false))
             {
                 return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
             }
@@ -275,7 +275,7 @@ namespace MediaBrowser.ApiInteraction
         {
             string url = ApiUrl + "/studios?userId=" + userId.ToString();
 
-            using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
+            using (Stream stream = await GetStreamAsync(url).ConfigureAwait(false))
             {
                 return JsonSerializer.DeserializeFromStream<IEnumerable<IBNItem<Studio>>>(stream);
             }
@@ -288,7 +288,7 @@ namespace MediaBrowser.ApiInteraction
         {
             string url = ApiUrl + "/itemlist?listtype=itemswithstudio&userId=" + userId.ToString() + "&name=" + name;
 
-            using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
+            using (Stream stream = await GetStreamAsync(url).ConfigureAwait(false))
             {
                 return JsonSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
             }
@@ -301,7 +301,7 @@ namespace MediaBrowser.ApiInteraction
         {
             string url = ApiUrl + "/studio?userId=" + userId.ToString() + "&name=" + name;
 
-            using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
+            using (Stream stream = await GetStreamAsync(url).ConfigureAwait(false))
             {
                 return JsonSerializer.DeserializeFromStream<IBNItem<Studio>>(stream);
             }
@@ -314,7 +314,7 @@ namespace MediaBrowser.ApiInteraction
         {
             string url = ApiUrl + "/genre?userId=" + userId.ToString() + "&name=" + name;
 
-            using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
+            using (Stream stream = await GetStreamAsync(url).ConfigureAwait(false))
             {
                 return JsonSerializer.DeserializeFromStream<IBNItem<Genre>>(stream);
             }
@@ -327,7 +327,7 @@ namespace MediaBrowser.ApiInteraction
         {
             string url = ApiUrl + "/person?userId=" + userId.ToString() + "&name=" + name;
 
-            using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
+            using (Stream stream = await GetStreamAsync(url).ConfigureAwait(false))
             {
                 return JsonSerializer.DeserializeFromStream<IBNItem<Person>>(stream);
             }
@@ -340,12 +340,17 @@ namespace MediaBrowser.ApiInteraction
         {
             string url = ApiUrl + "/year?userId=" + userId.ToString() + "&year=" + year;
 
-            using (Stream stream = await HttpClient.GetStreamAsync(url).ConfigureAwait(false))
+            using (Stream stream = await GetStreamAsync(url).ConfigureAwait(false))
             {
                 return JsonSerializer.DeserializeFromStream<IBNItem<Year>>(stream);
             }
         }
 
+        private Task<Stream> GetStreamAsync(string url)
+        {
+            return GetStreamAsync(url);
+        }
+
         public void Dispose()
         {
             HttpClient.Dispose();

+ 1 - 1
MediaBrowser.Controller/FFMpeg/FFProbeResult.cs

@@ -33,7 +33,7 @@ namespace MediaBrowser.Controller.FFMpeg
         public int channels { get; set; }
         //public int bits_per_sample { get; set; }
         //public string r_frame_rate { get; set; }
-        //public string avg_frame_rate { get; set; }
+        public string avg_frame_rate { get; set; }
         //public string time_base { get; set; }
         //public string start_time { get; set; }
         public string duration { get; set; }

+ 13 - 20
MediaBrowser.Controller/Providers/AudioInfoProvider.cs

@@ -144,37 +144,30 @@ namespace MediaBrowser.Controller.Providers
 
         private int? GetDictionaryDiscValue(Dictionary<string, string> tags)
         {
-            string[] keys = tags.Keys.ToArray();
+            string disc = GetDictionaryValue(tags, "disc");
 
-            for (int i = 0; i < keys.Length; i++)
+            if (!string.IsNullOrEmpty(disc))
             {
-                string currentKey = keys[i];
-
-                if ("disc".Equals(currentKey, StringComparison.OrdinalIgnoreCase))
-                {
-                    string disc = tags[currentKey];
-
-                    if (!string.IsNullOrEmpty(disc))
-                    {
-                        disc = disc.Split('/')[0];
+                disc = disc.Split('/')[0];
 
-                        int num;
+                int num;
 
-                        if (int.TryParse(disc, out num))
-                        {
-                            return num;
-                        }
-                    }
-
-                    break;
+                if (int.TryParse(disc, out num))
+                {
+                    return num;
                 }
             }
 
             return null;
         }
 
-        private string GetDictionaryValue(Dictionary<string, string> tags, string key)
+        internal static string GetDictionaryValue(Dictionary<string, string> tags, string key)
         {
+            if (tags == null)
+            {
+                return null;
+            }
+
             string[] keys = tags.Keys.ToArray();
 
             for (int i = 0; i < keys.Length; i++)

+ 57 - 3
MediaBrowser.Controller/Providers/VideoInfoProvider.cs

@@ -6,6 +6,7 @@ using System.Threading.Tasks;
 using MediaBrowser.Controller.Events;
 using MediaBrowser.Controller.FFMpeg;
 using MediaBrowser.Model.Entities;
+using System.Collections.Generic;
 
 namespace MediaBrowser.Controller.Providers
 {
@@ -61,11 +62,25 @@ namespace MediaBrowser.Controller.Providers
                 video.BitRate = int.Parse(data.format.bit_rate);
             }
 
-            MediaStream videoStream = data.streams.FirstOrDefault(s => s.codec_type.Equals("video", StringComparison.OrdinalIgnoreCase));
+            // For now, only read info about first video stream
+            // Files with multiple video streams are possible, but extremely rare
+            bool foundVideo = false;
 
-            if (videoStream != null)
+            foreach (MediaStream stream in data.streams)
             {
-                FetchFromVideoStream(video, videoStream);
+                if (stream.codec_type.Equals("video", StringComparison.OrdinalIgnoreCase))
+                {
+                    if (!foundVideo)
+                    {
+                        FetchFromVideoStream(video, stream);
+                    }
+
+                    foundVideo = true;
+                }
+                else if (stream.codec_type.Equals("audio", StringComparison.OrdinalIgnoreCase))
+                {
+                    FetchFromAudioStream(video, stream);
+                }
             }
         }
 
@@ -75,6 +90,45 @@ namespace MediaBrowser.Controller.Providers
             video.Width = stream.width;
             video.Height = stream.height;
             video.AspectRatio = stream.display_aspect_ratio;
+
+            if (!string.IsNullOrEmpty(stream.avg_frame_rate))
+            {
+                string[] parts = stream.avg_frame_rate.Split('/');
+
+                if (parts.Length == 2)
+                {
+                    video.FrameRate = float.Parse(parts[0]) / float.Parse(parts[1]);
+                }
+                else
+                {
+                    video.FrameRate = float.Parse(parts[0]);
+                }
+            }
+        }
+
+        private void FetchFromAudioStream(Video video, MediaStream stream)
+        {
+            AudioStream audio = new AudioStream();
+
+            audio.Codec = stream.codec_name;
+
+            if (!string.IsNullOrEmpty(stream.bit_rate))
+            {
+                audio.BitRate = int.Parse(stream.bit_rate);
+            }
+
+            audio.Channels = stream.channels;
+
+            if (!string.IsNullOrEmpty(stream.sample_rate))
+            {
+                audio.SampleRate = int.Parse(stream.sample_rate);
+            }
+
+            audio.Language = AudioInfoProvider.GetDictionaryValue(stream.tags, "language");
+
+            List<AudioStream> streams = (video.AudioStreams ?? new AudioStream[] { }).ToList();
+            streams.Add(audio);
+            video.AudioStreams = streams;
         }
         
         /// <summary>

+ 21 - 17
MediaBrowser.Controller/Xml/BaseItemXmlParser.cs

@@ -321,8 +321,15 @@ namespace MediaBrowser.Controller.Xml
                             break;
 
                         case "Subtitle":
-                            FetchMediaInfoSubtitles(reader.ReadSubtree(), item);
-                            break;
+                            {
+                                SubtitleStream stream = FetchMediaInfoSubtitles(reader.ReadSubtree());
+
+                                List<SubtitleStream> streams = (item.Subtitles ?? new SubtitleStream[] { }).ToList();
+                                streams.Add(stream);
+                                item.Subtitles = streams;
+
+                                break;
+                            }
 
                         default:
                             reader.Skip();
@@ -348,10 +355,6 @@ namespace MediaBrowser.Controller.Xml
                             stream.IsDefault = reader.ReadElementContentAsString() == "True";
                             break;
 
-                        case "Forced":
-                            stream.IsForced = reader.ReadElementContentAsString() == "True";
-                            break;
-
                         case "BitRate":
                             stream.BitRate = reader.ReadIntSafe();
                             break;
@@ -451,9 +454,9 @@ namespace MediaBrowser.Controller.Xml
             }
         }
 
-        private void FetchMediaInfoSubtitles(XmlReader reader, Video item)
+        private SubtitleStream FetchMediaInfoSubtitles(XmlReader reader)
         {
-            List<string> list = (item.Subtitles ?? new string[] { }).ToList();
+            SubtitleStream stream = new SubtitleStream();
 
             reader.MoveToContent();
 
@@ -464,15 +467,16 @@ namespace MediaBrowser.Controller.Xml
                     switch (reader.Name)
                     {
                         case "Language":
-                            {
-                                string genre = reader.ReadElementContentAsString();
+                            stream.Language = reader.ReadElementContentAsString();
+                            break;
 
-                                if (!string.IsNullOrWhiteSpace(genre))
-                                {
-                                    list.Add(genre);
-                                }
-                                break;
-                            }
+                        case "Default":
+                            stream.IsDefault = reader.ReadElementContentAsString() == "True";
+                            break;
+
+                        case "Forced":
+                            stream.IsForced = reader.ReadElementContentAsString() == "True";
+                            break;
 
                         default:
                             reader.Skip();
@@ -481,7 +485,7 @@ namespace MediaBrowser.Controller.Xml
                 }
             }
 
-            item.Subtitles = list;
+            return stream;
         }
 
         private void FetchFromTaglinesNode(XmlReader reader, T item)

+ 2 - 1
MediaBrowser.Model/DTO/DTOBaseItem.cs

@@ -91,7 +91,8 @@ namespace MediaBrowser.Model.DTO
         public ItemSpecialCounts SpecialCounts { get; set; }
 
         public AudioInfo AudioInfo { get; set; }
-        
+        public VideoInfo VideoInfo { get; set; }
+      
         public bool IsType(Type type)
         {
             return IsType(type.Name);

+ 18 - 0
MediaBrowser.Model/DTO/VideoInfo.cs

@@ -0,0 +1,18 @@
+using System.Collections.Generic;
+using MediaBrowser.Model.Entities;
+
+namespace MediaBrowser.Model.DTO
+{
+    public class VideoInfo
+    {
+        public string Codec { get; set; }
+        public int Height { get; set; }
+        public int Width { get; set; }
+        public string ScanType { get; set; }
+
+        public VideoType VideoType { get; set; }
+
+        public IEnumerable<SubtitleStream> Subtitles { get; set; }
+        public IEnumerable<AudioStream> AudioStreams { get; set; }
+    }
+}

+ 7 - 1
MediaBrowser.Model/Entities/Video.cs

@@ -6,7 +6,7 @@ namespace MediaBrowser.Model.Entities
     {
         public VideoType VideoType { get; set; }
 
-        public IEnumerable<string> Subtitles { get; set; }
+        public IEnumerable<SubtitleStream> Subtitles { get; set; }
         public IEnumerable<AudioStream> AudioStreams { get; set; }
 
         public int Height { get; set; }
@@ -25,6 +25,12 @@ namespace MediaBrowser.Model.Entities
         public int Channels { get; set; }
         public int SampleRate { get; set; }
         public bool IsDefault { get; set; }
+    }
+
+    public class SubtitleStream
+    {
+        public string Language { get; set; }
+        public bool IsDefault { get; set; }
         public bool IsForced { get; set; }
     }
 

+ 1 - 0
MediaBrowser.Model/MediaBrowser.Model.csproj

@@ -34,6 +34,7 @@
   <ItemGroup>
     <Compile Include="DTO\AudioInfo.cs" />
     <Compile Include="DTO\DTOBaseItem.cs" />
+    <Compile Include="DTO\VideoInfo.cs" />
     <Compile Include="Entities\Audio.cs" />
     <Compile Include="Entities\BaseEntity.cs" />
     <Compile Include="Entities\BaseItem.cs" />