Bläddra i källkod

Upgraded Protobuf, and added api support for it

LukePulverenti Luke Pulverenti luke pulverenti 12 år sedan
förälder
incheckning
cb7f04e4d3
31 ändrade filer med 286 tillägg och 58 borttagningar
  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.