2
0
Эх сурвалжийг харах

Upgraded Protobuf, and added api support for it

LukePulverenti Luke Pulverenti luke pulverenti 12 жил өмнө
parent
commit
cb7f04e4d3
31 өөрчлөгдсөн 286 нэмэгдсэн , 58 устгасан
  1. 12 2
      MediaBrowser.Api/ApiService.cs
  2. 1 1
      MediaBrowser.Api/HttpHandlers/GenreHandler.cs
  3. 1 1
      MediaBrowser.Api/HttpHandlers/GenresHandler.cs
  4. 1 1
      MediaBrowser.Api/HttpHandlers/ItemHandler.cs
  5. 1 1
      MediaBrowser.Api/HttpHandlers/ItemListHandler.cs
  6. 1 1
      MediaBrowser.Api/HttpHandlers/PersonHandler.cs
  7. 1 1
      MediaBrowser.Api/HttpHandlers/PluginConfigurationHandler.cs
  8. 1 1
      MediaBrowser.Api/HttpHandlers/PluginsHandler.cs
  9. 1 1
      MediaBrowser.Api/HttpHandlers/StudioHandler.cs
  10. 1 1
      MediaBrowser.Api/HttpHandlers/StudiosHandler.cs
  11. 5 4
      MediaBrowser.Api/HttpHandlers/UsersHandler.cs
  12. 1 1
      MediaBrowser.Api/HttpHandlers/YearHandler.cs
  13. 1 1
      MediaBrowser.Api/HttpHandlers/YearsHandler.cs
  14. 57 20
      MediaBrowser.ApiInteraction/ApiClient.cs
  15. 6 1
      MediaBrowser.ApiInteraction/IDataSerializer.cs
  16. 3 2
      MediaBrowser.Common/MediaBrowser.Common.csproj
  17. 1 1
      MediaBrowser.Common/Net/Handlers/BaseSerializationHandler.cs
  18. 1 1
      MediaBrowser.Common/packages.config
  19. 1 1
      MediaBrowser.Controller/Kernel.cs
  20. 2 2
      MediaBrowser.Controller/MediaBrowser.Controller.csproj
  21. 1 1
      MediaBrowser.Controller/packages.config
  22. 11 1
      MediaBrowser.Model/DTO/AudioInfo.cs
  23. 72 8
      MediaBrowser.Model/DTO/DTOBaseItem.cs
  24. 18 0
      MediaBrowser.Model/DTO/DTOUser.cs
  25. 19 2
      MediaBrowser.Model/DTO/IBNItem.cs
  26. 13 0
      MediaBrowser.Model/DTO/PluginInfo.cs
  27. 13 0
      MediaBrowser.Model/DTO/VideoInfo.cs
  28. 10 1
      MediaBrowser.Model/Entities/ItemSpecialCounts.cs
  29. 5 0
      MediaBrowser.Model/Entities/UserItemData.cs
  30. 19 0
      MediaBrowser.Model/Entities/Video.cs
  31. 6 0
      MediaBrowser.Model/MediaBrowser.Model.csproj

+ 12 - 2
MediaBrowser.Api/ApiService.cs

@@ -171,7 +171,7 @@ namespace MediaBrowser.Api
                     }
 
                     return baseItemStudio;
-                });
+                }).ToArray();
             }
         }
 
@@ -218,7 +218,7 @@ namespace MediaBrowser.Api
                     }
 
                     return baseItemPerson;
-                });
+                }).ToArray();
             }
         }
 
@@ -269,5 +269,15 @@ namespace MediaBrowser.Api
                 Name = entity.Name
             };
         }
+
+        public static DTOUser GetDTOUser(User user)
+        {
+            return new DTOUser()
+            {
+                Id = user.Id,
+                Name = user.Name,
+                HasImage = !string.IsNullOrEmpty(user.PrimaryImagePath)
+            };
+        }
     }
 }

+ 1 - 1
MediaBrowser.Api/HttpHandlers/GenreHandler.cs

@@ -12,7 +12,7 @@ namespace MediaBrowser.Api.HttpHandlers
     /// <summary>
     /// Gets a single genre
     /// </summary>
-    public class GenreHandler : BaseSerializationHandler<IBNItem>
+    public class GenreHandler : BaseJsonHandler<IBNItem>
     {
         protected override Task<IBNItem> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/GenresHandler.cs

@@ -9,7 +9,7 @@ using MediaBrowser.Model.Entities;
 
 namespace MediaBrowser.Api.HttpHandlers
 {
-    public class GenresHandler : BaseSerializationHandler<IEnumerable<IBNItem>>
+    public class GenresHandler : BaseJsonHandler<IEnumerable<IBNItem>>
     {
         protected override Task<IEnumerable<IBNItem>> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/ItemHandler.cs

@@ -8,7 +8,7 @@ using MediaBrowser.Model.Entities;
 
 namespace MediaBrowser.Api.HttpHandlers
 {
-    public class ItemHandler : BaseSerializationHandler<DTOBaseItem>
+    public class ItemHandler : BaseJsonHandler<DTOBaseItem>
     {
         protected override Task<DTOBaseItem> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/ItemListHandler.cs

@@ -9,7 +9,7 @@ using MediaBrowser.Model.Entities;
 
 namespace MediaBrowser.Api.HttpHandlers
 {
-    public class ItemListHandler : BaseSerializationHandler<DTOBaseItem[]>
+    public class ItemListHandler : BaseJsonHandler<DTOBaseItem[]>
     {
         protected override Task<DTOBaseItem[]> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/PersonHandler.cs

@@ -12,7 +12,7 @@ namespace MediaBrowser.Api.HttpHandlers
     /// <summary>
     /// Gets a single Person
     /// </summary>
-    public class PersonHandler : BaseSerializationHandler<IBNItem>
+    public class PersonHandler : BaseJsonHandler<IBNItem>
     {
         protected override Task<IBNItem> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/PluginConfigurationHandler.cs

@@ -7,7 +7,7 @@ using MediaBrowser.Model.Plugins;
 
 namespace MediaBrowser.Api.HttpHandlers
 {
-    public class PluginConfigurationHandler : BaseSerializationHandler<BasePluginConfiguration>
+    public class PluginConfigurationHandler : BaseJsonHandler<BasePluginConfiguration>
     {
         protected override Task<BasePluginConfiguration> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/PluginsHandler.cs

@@ -10,7 +10,7 @@ namespace MediaBrowser.Api.HttpHandlers
     /// <summary>
     /// Provides information about installed plugins
     /// </summary>
-    public class PluginsHandler : BaseSerializationHandler<IEnumerable<PluginInfo>>
+    public class PluginsHandler : BaseJsonHandler<IEnumerable<PluginInfo>>
     {
         protected override Task<IEnumerable<PluginInfo>> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/StudioHandler.cs

@@ -12,7 +12,7 @@ namespace MediaBrowser.Api.HttpHandlers
     /// <summary>
     /// Gets a single studio
     /// </summary>
-    public class StudioHandler : BaseSerializationHandler<IBNItem>
+    public class StudioHandler : BaseJsonHandler<IBNItem>
     {
         protected override Task<IBNItem> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/StudiosHandler.cs

@@ -9,7 +9,7 @@ using MediaBrowser.Model.Entities;
 
 namespace MediaBrowser.Api.HttpHandlers
 {
-    public class StudiosHandler : BaseSerializationHandler<IEnumerable<IBNItem>>
+    public class StudiosHandler : BaseJsonHandler<IEnumerable<IBNItem>>
     {
         protected override Task<IEnumerable<IBNItem>> GetObjectToSerialize()
         {

+ 5 - 4
MediaBrowser.Api/HttpHandlers/UsersHandler.cs

@@ -1,16 +1,17 @@
 using System.Collections.Generic;
+using System.Linq;
 using System.Threading.Tasks;
 using MediaBrowser.Common.Net.Handlers;
 using MediaBrowser.Controller;
-using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.DTO;
 
 namespace MediaBrowser.Api.HttpHandlers
 {
-    class UsersHandler : BaseSerializationHandler<IEnumerable<User>>
+    class UsersHandler : BaseJsonHandler<IEnumerable<DTOUser>>
     {
-        protected override Task<IEnumerable<User>> GetObjectToSerialize()
+        protected override Task<IEnumerable<DTOUser>> GetObjectToSerialize()
         {
-            return Task.FromResult<IEnumerable<User>>(Kernel.Instance.Users);
+            return Task.FromResult<IEnumerable<DTOUser>>(Kernel.Instance.Users.Select(u => ApiService.GetDTOUser(u)));
         }
     }
 }

+ 1 - 1
MediaBrowser.Api/HttpHandlers/YearHandler.cs

@@ -12,7 +12,7 @@ namespace MediaBrowser.Api.HttpHandlers
     /// <summary>
     /// Gets a single year
     /// </summary>
-    public class YearHandler : BaseSerializationHandler<IBNItem>
+    public class YearHandler : BaseJsonHandler<IBNItem>
     {
         protected override Task<IBNItem> GetObjectToSerialize()
         {

+ 1 - 1
MediaBrowser.Api/HttpHandlers/YearsHandler.cs

@@ -9,7 +9,7 @@ using MediaBrowser.Model.Entities;
 
 namespace MediaBrowser.Api.HttpHandlers
 {
-    public class YearsHandler : BaseSerializationHandler<IEnumerable<IBNItem>>
+    public class YearsHandler : BaseJsonHandler<IEnumerable<IBNItem>>
     {
         protected override Task<IEnumerable<IBNItem>> GetObjectToSerialize()
         {

+ 57 - 20
MediaBrowser.ApiInteraction/ApiClient.cs

@@ -40,10 +40,27 @@ namespace MediaBrowser.ApiInteraction
         }
 
         /// <summary>
-        /// Gets or sets the format to request from the server
-        /// The Data Serializer will have to be able to support it.
+        /// Gets the data format to request from the server
         /// </summary>
-        public SerializationFormat SerializationFormat { get; set; }
+        private SerializationFormat SerializationFormat
+        {
+            get
+            {
+                // First try Protobuf since it has the best performance
+                if (DataSerializer.CanDeserializeProtobuf)
+                {
+                    return ApiInteraction.SerializationFormat.Protobuf;
+                }
+
+                // Next best is jsv
+                if (DataSerializer.CanDeserializeJsv)
+                {
+                    return ApiInteraction.SerializationFormat.Jsv;
+                }
+
+                return ApiInteraction.SerializationFormat.Json;
+            }
+        }
 
         public HttpClient HttpClient { get; private set; }
         public IDataSerializer DataSerializer { get; set; }
@@ -288,7 +305,7 @@ namespace MediaBrowser.ApiInteraction
 
             return url;
         }
-        
+
         /// <summary>
         /// This is a helper to get a list of backdrop url's from a given ApiBaseItemWrapper. If the actual item does not have any backdrops it will return backdrops from the first parent that does.
         /// </summary>
@@ -372,20 +389,20 @@ namespace MediaBrowser.ApiInteraction
 
             using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false))
             {
-                return DataSerializer.DeserializeFromStream<DTOBaseItem>(stream);
+                return DeserializeFromStream<DTOBaseItem>(stream);
             }
         }
 
         /// <summary>
         /// Gets all Users
         /// </summary>
-        public async Task<IEnumerable<User>> GetAllUsersAsync()
+        public async Task<IEnumerable<DTOUser>> GetAllUsersAsync()
         {
             string url = ApiUrl + "/users";
 
             using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false))
             {
-                return DataSerializer.DeserializeFromStream<IEnumerable<User>>(stream);
+                return DeserializeFromStream<DTOUser[]>(stream);
             }
         }
 
@@ -398,7 +415,7 @@ namespace MediaBrowser.ApiInteraction
 
             using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false))
             {
-                return DataSerializer.DeserializeFromStream<IEnumerable<IBNItem>>(stream);
+                return DeserializeFromStream<IBNItem[]>(stream);
             }
         }
 
@@ -411,7 +428,7 @@ namespace MediaBrowser.ApiInteraction
 
             using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false))
             {
-                return DataSerializer.DeserializeFromStream<IEnumerable<IBNItem>>(stream);
+                return DeserializeFromStream<IBNItem[]>(stream);
             }
         }
 
@@ -424,7 +441,7 @@ namespace MediaBrowser.ApiInteraction
 
             using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false))
             {
-                return DataSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
+                return DeserializeFromStream<DTOBaseItem[]>(stream);
             }
         }
 
@@ -437,7 +454,7 @@ namespace MediaBrowser.ApiInteraction
 
             using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false))
             {
-                return DataSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
+                return DeserializeFromStream<DTOBaseItem[]>(stream);
             }
         }
 
@@ -450,7 +467,7 @@ namespace MediaBrowser.ApiInteraction
 
             using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false))
             {
-                return DataSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
+                return DeserializeFromStream<DTOBaseItem[]>(stream);
             }
         }
 
@@ -465,7 +482,7 @@ namespace MediaBrowser.ApiInteraction
 
             using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false))
             {
-                return DataSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
+                return DeserializeFromStream<DTOBaseItem[]>(stream);
             }
         }
 
@@ -478,7 +495,7 @@ namespace MediaBrowser.ApiInteraction
 
             using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false))
             {
-                return DataSerializer.DeserializeFromStream<IEnumerable<IBNItem>>(stream);
+                return DeserializeFromStream<IBNItem[]>(stream);
             }
         }
 
@@ -491,7 +508,7 @@ namespace MediaBrowser.ApiInteraction
 
             using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false))
             {
-                return DataSerializer.DeserializeFromStream<IEnumerable<DTOBaseItem>>(stream);
+                return DeserializeFromStream<DTOBaseItem[]>(stream);
             }
         }
 
@@ -504,7 +521,7 @@ namespace MediaBrowser.ApiInteraction
 
             using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false))
             {
-                return DataSerializer.DeserializeFromStream<IBNItem>(stream);
+                return DeserializeFromStream<IBNItem>(stream);
             }
         }
 
@@ -517,7 +534,7 @@ namespace MediaBrowser.ApiInteraction
 
             using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false))
             {
-                return DataSerializer.DeserializeFromStream<IBNItem>(stream);
+                return DeserializeFromStream<IBNItem>(stream);
             }
         }
 
@@ -530,7 +547,7 @@ namespace MediaBrowser.ApiInteraction
 
             using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false))
             {
-                return DataSerializer.DeserializeFromStream<IBNItem>(stream);
+                return DeserializeFromStream<IBNItem>(stream);
             }
         }
 
@@ -543,7 +560,7 @@ namespace MediaBrowser.ApiInteraction
 
             using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false))
             {
-                return DataSerializer.DeserializeFromStream<IBNItem>(stream);
+                return DeserializeFromStream<IBNItem>(stream);
             }
         }
 
@@ -564,6 +581,25 @@ namespace MediaBrowser.ApiInteraction
             return GetStreamAsync(url);
         }
 
+        private T DeserializeFromStream<T>(Stream stream)
+        {
+            return DeserializeFromStream<T>(stream, SerializationFormat);
+        }
+
+        private T DeserializeFromStream<T>(Stream stream, SerializationFormat format)
+        {
+            if (format == ApiInteraction.SerializationFormat.Protobuf)
+            {
+                return DataSerializer.DeserializeProtobufFromStream<T>(stream);
+            }
+            if (format == ApiInteraction.SerializationFormat.Jsv)
+            {
+                return DataSerializer.DeserializeJsvFromStream<T>(stream);
+            }
+
+            return DataSerializer.DeserializeJsonFromStream<T>(stream);
+        }
+
         /// <summary>
         /// This is just a helper around HttpClient
         /// </summary>
@@ -581,6 +617,7 @@ namespace MediaBrowser.ApiInteraction
     public enum SerializationFormat
     {
         Json,
-        Jsv
+        Jsv,
+        Protobuf
     }
 }

+ 6 - 1
MediaBrowser.ApiInteraction/IDataSerializer.cs

@@ -8,6 +8,11 @@ namespace MediaBrowser.ApiInteraction
     /// </summary>
     public interface IDataSerializer
     {
-        T DeserializeFromStream<T>(Stream stream);
+        T DeserializeJsonFromStream<T>(Stream stream);
+        T DeserializeJsvFromStream<T>(Stream stream);
+        T DeserializeProtobufFromStream<T>(Stream stream);
+
+        bool CanDeserializeJsv { get; }
+        bool CanDeserializeProtobuf { get; }
     }
 }

+ 3 - 2
MediaBrowser.Common/MediaBrowser.Common.csproj

@@ -36,8 +36,9 @@
     </Reference>
     <Reference Include="PresentationCore" />
     <Reference Include="PresentationFramework" />
-    <Reference Include="protobuf-net">
-      <HintPath>..\packages\protobuf-net.2.0.0.480\lib\net40\protobuf-net.dll</HintPath>
+    <Reference Include="protobuf-net, Version=2.0.0.580, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\packages\protobuf-net.2.0.0.580\lib\net40\protobuf-net.dll</HintPath>
     </Reference>
     <Reference Include="ServiceStack.Text, Version=3.9.5.0, Culture=neutral, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>

+ 1 - 1
MediaBrowser.Common/Net/Handlers/BaseSerializationHandler.cs

@@ -5,7 +5,7 @@ using MediaBrowser.Common.Serialization;
 
 namespace MediaBrowser.Common.Net.Handlers
 {
-    public abstract class BaseSerializationHandler<T> : BaseHandler
+    public abstract class BaseJsonHandler<T> : BaseHandler
     {
         public SerializationFormat SerializationFormat
         {

+ 1 - 1
MediaBrowser.Common/packages.config

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="MahApps.Metro" version="0.9.0.0" targetFramework="net45" />
-  <package id="protobuf-net" version="2.0.0.480" targetFramework="net45" />
+  <package id="protobuf-net" version="2.0.0.580" targetFramework="net45" />
   <package id="Rx-Core" version="2.0.20823" targetFramework="net45" />
   <package id="Rx-Interfaces" version="2.0.20823" targetFramework="net45" />
   <package id="Rx-Linq" version="2.0.20823" targetFramework="net45" />

+ 1 - 1
MediaBrowser.Controller/Kernel.cs

@@ -228,7 +228,7 @@ namespace MediaBrowser.Controller
 
             user.Name = "Default User";
             user.Id = Guid.Parse("5d1cf7fce25943b790d140095457a42b");
-            user.PrimaryImagePath = "D:\\Video\\TV\\Archer (2009)\\folder.jpg";
+            //user.PrimaryImagePath = "D:\\Video\\TV\\Archer (2009)\\folder.jpg";
 
             list.Add(user);
             

+ 2 - 2
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -30,9 +30,9 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="protobuf-net, Version=2.0.0.480, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
+    <Reference Include="protobuf-net, Version=2.0.0.580, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\protobuf-net.2.0.0.480\lib\net40\protobuf-net.dll</HintPath>
+      <HintPath>..\packages\protobuf-net.2.0.0.580\lib\net40\protobuf-net.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.ComponentModel.Composition" />

+ 1 - 1
MediaBrowser.Controller/packages.config

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="protobuf-net" version="2.0.0.480" targetFramework="net45" />
+  <package id="protobuf-net" version="2.0.0.580" targetFramework="net45" />
   <package id="Rx-Core" version="2.0.20823" targetFramework="net45" />
   <package id="Rx-Interfaces" version="2.0.20823" targetFramework="net45" />
   <package id="Rx-Linq" version="2.0.20823" targetFramework="net45" />

+ 11 - 1
MediaBrowser.Model/DTO/AudioInfo.cs

@@ -1,13 +1,23 @@
-
+using ProtoBuf;
+
 namespace MediaBrowser.Model.DTO
 {
+    [ProtoContract]
     public class AudioInfo
     {
+        [ProtoMember(1)]
         public int BitRate { get; set; }
+
+        [ProtoMember(2)]
         public int Channels { get; set; }
 
+        [ProtoMember(3)]
         public string Artist { get; set; }
+
+        [ProtoMember(4)]
         public string Album { get; set; }
+
+        [ProtoMember(5)]
         public string AlbumArtist { get; set; }
     }
 }

+ 72 - 8
MediaBrowser.Model/DTO/DTOBaseItem.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using MediaBrowser.Model.Entities;
+using ProtoBuf;
 
 namespace MediaBrowser.Model.DTO
 {
@@ -8,89 +9,151 @@ namespace MediaBrowser.Model.DTO
     /// This is strictly used as a data transfer object from the api layer.
     /// This holds information about a BaseItem in a format that is convenient for the client.
     /// </summary>
+    [ProtoContract]
     public class DTOBaseItem : IHasProviderIds
     {
+        [ProtoMember(1)]
         public string Name { get; set; }
+
+        [ProtoMember(2)]
         public Guid Id { get; set; }
+
+        [ProtoMember(3)]
         public DateTime DateCreated { get; set; }
 
+        [ProtoMember(4)]
         public string SortName { get; set; }
+
+        [ProtoMember(5)]
         public DateTime? PremiereDate { get; set; }
+
+        [ProtoMember(6)]
         public string Path { get; set; }
+
+        [ProtoMember(7)]
         public string OfficialRating { get; set; }
+
+        [ProtoMember(8)]
         public string Overview { get; set; }
-        public IEnumerable<string> Taglines { get; set; }
 
-        public IEnumerable<string> Genres { get; set; }
+        [ProtoMember(9)]
+        public IList<string> Taglines { get; set; }
+
+        [ProtoMember(10)]
+        public IList<string> Genres { get; set; }
 
+        [ProtoMember(11)]
         public string DisplayMediaType { get; set; }
 
+        [ProtoMember(12)]
         public float? UserRating { get; set; }
+
+        [ProtoMember(13)]
         public long? RunTimeTicks { get; set; }
 
+        [ProtoMember(14)]
         public string AspectRatio { get; set; }
+
+        [ProtoMember(15)]
         public int? ProductionYear { get; set; }
 
+        [ProtoMember(16)]
         public int? IndexNumber { get; set; }
+
+        [ProtoMember(17)]
         public int? ParentIndexNumber { get; set; }
 
+        [ProtoMember(18)]
         public string TrailerUrl { get; set; }
 
+        [ProtoMember(19)]
         public Dictionary<string, string> ProviderIds { get; set; }
 
+        [ProtoMember(20)]
         public bool HasBanner { get; set; }
+
+        [ProtoMember(21)]
         public bool HasArt { get; set; }
+
+        [ProtoMember(22)]
         public bool HasLogo { get; set; }
+
+        [ProtoMember(23)]
         public bool HasThumb { get; set; }
+
+        [ProtoMember(24)]
         public bool HasPrimaryImage { get; set; }
 
+        [ProtoMember(25)]
         public string Language { get; set; }
-        
+
+        [ProtoMember(26)]
         public int BackdropCount { get; set; }
 
-        public IEnumerable<DTOBaseItem> Children { get; set; }
+        [ProtoMember(27)]
+        public DTOBaseItem[] Children { get; set; }
 
+        [ProtoMember(28)]
         public bool IsFolder { get; set; }
 
         /// <summary>
         /// If the item is a Folder this will determine if it's the Root or not
         /// </summary>
+        [ProtoMember(29)]
         public bool? IsRoot { get; set; }
 
         /// <summary>
         /// If the item is a Folder this will determine if it's a VF or not
         /// </summary>
+        [ProtoMember(30)]
         public bool? IsVirtualFolder { get; set; }
-        
+
+        [ProtoMember(31)]
         public Guid? ParentId { get; set; }
 
+        [ProtoMember(32)]
         public string Type { get; set; }
 
-        public IEnumerable<BaseItemPerson> People { get; set; }
-        public IEnumerable<BaseItemStudio> Studios { get; set; }
+        [ProtoMember(33)]
+        public BaseItemPerson[] People { get; set; }
+
+        [ProtoMember(34)]
+        public BaseItemStudio[] Studios { get; set; }
 
         /// <summary>
         /// If the item does not have a logo, this will hold the Id of the Parent that has one.
         /// </summary>
+        [ProtoMember(35)]
         public Guid? ParentLogoItemId { get; set; }
 
         /// <summary>
         /// If the item does not have any backdrops, this will hold the Id of the Parent that has one.
         /// </summary>
+        [ProtoMember(36)]
         public Guid? ParentBackdropItemId { get; set; }
+
+        [ProtoMember(37)]
         public int? ParentBackdropCount { get; set; }
 
-        public IEnumerable<DTOBaseItem> LocalTrailers { get; set; }
+        [ProtoMember(38)]
+        public DTOBaseItem[] LocalTrailers { get; set; }
+
+        [ProtoMember(39)]
         public int LocalTrailerCount { get; set; }
 
         /// <summary>
         /// User data for this item based on the user it's being requested for
         /// </summary>
+        [ProtoMember(40)]
         public UserItemData UserData { get; set; }
 
+        [ProtoMember(41)]
         public ItemSpecialCounts SpecialCounts { get; set; }
 
+        [ProtoMember(42)]
         public AudioInfo AudioInfo { get; set; }
+
+        [ProtoMember(43)]
         public VideoInfo VideoInfo { get; set; }
       
         public bool IsType(Type type)
@@ -103,6 +166,7 @@ namespace MediaBrowser.Model.DTO
             return Type.Equals(type, StringComparison.OrdinalIgnoreCase);
         }
 
+        [ProtoMember(44)]
         public bool IsNew { get; set; }
     }
 }

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

@@ -0,0 +1,18 @@
+using System;
+using ProtoBuf;
+
+namespace MediaBrowser.Model.DTO
+{
+    [ProtoContract]
+    public class DTOUser
+    {
+        [ProtoMember(1)]
+        public string Name { get; set; }
+
+        [ProtoMember(2)]
+        public Guid Id { get; set; }
+
+        [ProtoMember(3)]
+        public bool HasImage { get; set; }
+    }
+}

+ 19 - 2
MediaBrowser.Model/DTO/IBNItem.cs

@@ -1,48 +1,65 @@
-using MediaBrowser.Model.Entities;
-using System;
+using System;
+using ProtoBuf;
 
 namespace MediaBrowser.Model.DTO
 {
     /// <summary>
     /// This is a stub class used by the api to get IBN types along with their item counts
     /// </summary>
+    [ProtoContract]
     public class IBNItem
     {
         /// <summary>
         /// The name of the person, genre, etc
         /// </summary>
+        [ProtoMember(1)]
         public string Name { get; set; }
 
         /// <summary>
         /// The id of the person, genre, etc
         /// </summary>
+        [ProtoMember(2)]
         public Guid Id { get; set; }
 
+        [ProtoMember(3)]
         public bool HasImage { get; set; }
 
         /// <summary>
         /// The number of items that have the genre, year, studio, etc
         /// </summary>
+        [ProtoMember(4)]
         public int BaseItemCount { get; set; }
     }
 
     /// <summary>
     /// This is used by the api to get information about a Person within a BaseItem
     /// </summary>
+    [ProtoContract]
     public class BaseItemPerson
     {
+        [ProtoMember(1)]
         public string Name { get; set; }
+
+        [ProtoMember(2)]
         public string Overview { get; set; }
+
+        [ProtoMember(3)]
         public string Type { get; set; }
+
+        [ProtoMember(4)]
         public bool HasImage { get; set; }
     }
 
     /// <summary>
     /// This is used by the api to get information about a studio within a BaseItem
     /// </summary>
+    [ProtoContract]
     public class BaseItemStudio
     {
+        [ProtoMember(1)]
         public string Name { get; set; }
+
+        [ProtoMember(2)]
         public bool HasImage { get; set; }
     }
 }

+ 13 - 0
MediaBrowser.Model/DTO/PluginInfo.cs

@@ -1,17 +1,30 @@
 using System;
+using ProtoBuf;
 
 namespace MediaBrowser.Model.DTO
 {
     /// <summary>
     /// This is a serializable stub class that is used by the api to provide information about installed plugins.
     /// </summary>
+    [ProtoContract]
     public class PluginInfo
     {
+        [ProtoMember(1)]
         public string Name { get; set; }
+
+        [ProtoMember(2)]
         public string Path { get; set; }
+
+        [ProtoMember(3)]
         public bool Enabled { get; set; }
+
+        [ProtoMember(4)]
         public bool DownloadToUI { get; set; }
+
+        [ProtoMember(5)]
         public DateTime ConfigurationDateLastModified { get; set; }
+
+        [ProtoMember(6)]
         public Version Version { get; set; }
     }
 }

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

@@ -1,18 +1,31 @@
 using System.Collections.Generic;
 using MediaBrowser.Model.Entities;
+using ProtoBuf;
 
 namespace MediaBrowser.Model.DTO
 {
+    [ProtoContract]
     public class VideoInfo
     {
+        [ProtoMember(1)]
         public string Codec { get; set; }
+
+        [ProtoMember(2)]
         public int Height { get; set; }
+
+        [ProtoMember(3)]
         public int Width { get; set; }
+
+        [ProtoMember(4)]
         public string ScanType { get; set; }
 
+        [ProtoMember(5)]
         public VideoType VideoType { get; set; }
 
+        [ProtoMember(6)]
         public IEnumerable<SubtitleStream> Subtitles { get; set; }
+
+        [ProtoMember(7)]
         public IEnumerable<AudioStream> AudioStreams { get; set; }
     }
 }

+ 10 - 1
MediaBrowser.Model/Entities/ItemSpecialCounts.cs

@@ -1,14 +1,23 @@
-
+using ProtoBuf;
+
 namespace MediaBrowser.Model.Entities
 {
     /// <summary>
     /// Since it can be slow to collect this data, this class helps provide a way to calculate them all at once.
     /// </summary>
+    [ProtoContract]
     public class ItemSpecialCounts
     {
+        [ProtoMember(1)]
         public int RecentlyAddedItemCount { get; set; }
+
+        [ProtoMember(2)]
         public int RecentlyAddedUnPlayedItemCount { get; set; }
+
+        [ProtoMember(3)]
         public int InProgressItemCount { get; set; }
+
+        [ProtoMember(4)]
         public decimal PlayedPercentage { get; set; }
     }
 }

+ 5 - 0
MediaBrowser.Model/Entities/UserItemData.cs

@@ -1,13 +1,18 @@
 using System;
+using ProtoBuf;
 
 namespace MediaBrowser.Model.Entities
 {
+    [ProtoContract]
     public class UserItemData
     {
+        [ProtoMember(1)]
         public UserItemRating Rating { get; set; }
 
+        [ProtoMember(2)]
         public long PlaybackPositionTicks { get; set; }
 
+        [ProtoMember(3)]
         public int PlayCount { get; set; }
     }
 

+ 19 - 0
MediaBrowser.Model/Entities/Video.cs

@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using ProtoBuf;
 
 namespace MediaBrowser.Model.Entities
 {
@@ -17,20 +18,38 @@ namespace MediaBrowser.Model.Entities
         public string Codec { get; set; }
     }
 
+    [ProtoContract]
     public class AudioStream
     {
+        [ProtoMember(1)]
         public string Codec { get; set; }
+
+        [ProtoMember(2)]
         public string Language { get; set; }
+
+        [ProtoMember(3)]
         public int BitRate { get; set; }
+
+        [ProtoMember(4)]
         public int Channels { get; set; }
+
+        [ProtoMember(5)]
         public int SampleRate { get; set; }
+
+        [ProtoMember(6)]
         public bool IsDefault { get; set; }
     }
 
+    [ProtoContract]
     public class SubtitleStream
     {
+        [ProtoMember(1)]
         public string Language { get; set; }
+
+        [ProtoMember(2)]
         public bool IsDefault { get; set; }
+
+        [ProtoMember(2)]
         public bool IsForced { get; set; }
     }
 

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

@@ -34,6 +34,7 @@
   <ItemGroup>
     <Compile Include="DTO\AudioInfo.cs" />
     <Compile Include="DTO\DTOBaseItem.cs" />
+    <Compile Include="DTO\DTOUser.cs" />
     <Compile Include="DTO\VideoInfo.cs" />
     <Compile Include="Entities\Audio.cs" />
     <Compile Include="Entities\BaseEntity.cs" />
@@ -56,6 +57,11 @@
     <Compile Include="Entities\User.cs" />
     <Compile Include="Entities\UserItemData.cs" />
   </ItemGroup>
+  <ItemGroup>
+    <Reference Include="protobuf-net">
+      <HintPath>..\packages\protobuf-net.2.0.0.580\lib\sl4\protobuf-net.dll</HintPath>
+    </Reference>
+  </ItemGroup>
   <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.