BaseApiClient.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814
  1. using MediaBrowser.Model.Connectivity;
  2. using MediaBrowser.Model.Dto;
  3. using MediaBrowser.Model.Entities;
  4. using MediaBrowser.Model.Logging;
  5. using MediaBrowser.Model.Web;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.IO;
  9. using System.Linq;
  10. namespace MediaBrowser.ApiInteraction
  11. {
  12. /// <summary>
  13. /// Provides api methods that are usable on all platforms
  14. /// </summary>
  15. public abstract class BaseApiClient : IDisposable
  16. {
  17. /// <summary>
  18. /// Gets the logger.
  19. /// </summary>
  20. /// <value>The logger.</value>
  21. protected ILogger Logger { get; private set; }
  22. /// <summary>
  23. /// Initializes a new instance of the <see cref="BaseApiClient" /> class.
  24. /// </summary>
  25. /// <param name="logger">The logger.</param>
  26. /// <exception cref="System.ArgumentNullException">logger</exception>
  27. protected BaseApiClient(ILogger logger)
  28. {
  29. if (logger == null)
  30. {
  31. throw new ArgumentNullException("logger");
  32. }
  33. Logger = logger;
  34. DataSerializer.Configure();
  35. }
  36. /// <summary>
  37. /// Gets or sets the server host name (myserver or 192.168.x.x)
  38. /// </summary>
  39. /// <value>The name of the server host.</value>
  40. public string ServerHostName { get; set; }
  41. /// <summary>
  42. /// Gets or sets the port number used by the API
  43. /// </summary>
  44. /// <value>The server API port.</value>
  45. public int ServerApiPort { get; set; }
  46. /// <summary>
  47. /// Gets or sets the type of the client.
  48. /// </summary>
  49. /// <value>The type of the client.</value>
  50. public ClientType ClientType { get; set; }
  51. /// <summary>
  52. /// Gets or sets the name of the device.
  53. /// </summary>
  54. /// <value>The name of the device.</value>
  55. public string DeviceName { get; set; }
  56. private Guid? _currentUserId;
  57. /// <summary>
  58. /// Gets or sets the current user id.
  59. /// </summary>
  60. /// <value>The current user id.</value>
  61. public virtual Guid? CurrentUserId
  62. {
  63. get { return _currentUserId; }
  64. set
  65. {
  66. _currentUserId = value;
  67. ResetAuthorizationHeader();
  68. }
  69. }
  70. /// <summary>
  71. /// Gets the current api url based on hostname and port.
  72. /// </summary>
  73. /// <value>The API URL.</value>
  74. protected string ApiUrl
  75. {
  76. get
  77. {
  78. return string.Format("http://{0}:{1}/mediabrowser", ServerHostName, ServerApiPort);
  79. }
  80. }
  81. private SerializationFormats _serializationFormat = SerializationFormats.Protobuf;
  82. /// <summary>
  83. /// Gets the default data format to request from the server
  84. /// </summary>
  85. /// <value>The serialization format.</value>
  86. public SerializationFormats SerializationFormat
  87. {
  88. get
  89. {
  90. return _serializationFormat;
  91. }
  92. set
  93. {
  94. _serializationFormat = value;
  95. }
  96. }
  97. /// <summary>
  98. /// Resets the authorization header.
  99. /// </summary>
  100. private void ResetAuthorizationHeader()
  101. {
  102. if (!CurrentUserId.HasValue)
  103. {
  104. SetAuthorizationHeader(null);
  105. return;
  106. }
  107. var header = string.Format("UserId=\"{0}\", Client=\"{1}\"", CurrentUserId.Value, ClientType);
  108. if (!string.IsNullOrEmpty(DeviceName))
  109. {
  110. header += string.Format(", Device=\"{0}\"", DeviceName);
  111. }
  112. SetAuthorizationHeader(header);
  113. }
  114. /// <summary>
  115. /// Sets the authorization header.
  116. /// </summary>
  117. /// <param name="header">The header.</param>
  118. protected abstract void SetAuthorizationHeader(string header);
  119. /// <summary>
  120. /// Gets the API URL.
  121. /// </summary>
  122. /// <param name="handler">The handler.</param>
  123. /// <returns>System.String.</returns>
  124. /// <exception cref="System.ArgumentNullException">handler</exception>
  125. protected string GetApiUrl(string handler)
  126. {
  127. return GetApiUrl(handler, new QueryStringDictionary());
  128. }
  129. /// <summary>
  130. /// Gets the API URL.
  131. /// </summary>
  132. /// <param name="handler">The handler.</param>
  133. /// <param name="queryString">The query string.</param>
  134. /// <returns>System.String.</returns>
  135. /// <exception cref="System.ArgumentNullException">handler</exception>
  136. protected string GetApiUrl(string handler, QueryStringDictionary queryString)
  137. {
  138. if (string.IsNullOrEmpty(handler))
  139. {
  140. throw new ArgumentNullException("handler");
  141. }
  142. if (queryString == null)
  143. {
  144. throw new ArgumentNullException("queryString");
  145. }
  146. return queryString.GetUrl(ApiUrl + "/" + handler);
  147. }
  148. /// <summary>
  149. /// Creates a url to return a list of items
  150. /// </summary>
  151. /// <param name="query">The query.</param>
  152. /// <param name="listType">The type of list to retrieve.</param>
  153. /// <returns>System.String.</returns>
  154. /// <exception cref="System.ArgumentNullException">query</exception>
  155. protected string GetItemListUrl(ItemQuery query, string listType = null)
  156. {
  157. if (query == null)
  158. {
  159. throw new ArgumentNullException("query");
  160. }
  161. var dict = new QueryStringDictionary { };
  162. dict.AddIfNotNullOrEmpty("listtype", listType);
  163. dict.AddIfNotNullOrEmpty("ParentId", query.ParentId);
  164. dict.AddIfNotNull("startindex", query.StartIndex);
  165. dict.AddIfNotNull("limit", query.Limit);
  166. if (query.SortBy != null)
  167. {
  168. dict["sortBy"] = string.Join(",", query.SortBy.Select(s => s.ToString()));
  169. }
  170. if (query.SortOrder.HasValue)
  171. {
  172. dict["sortOrder"] = query.SortOrder.ToString();
  173. }
  174. if (query.Fields != null)
  175. {
  176. dict.Add("fields", query.Fields.Select(f => f.ToString()));
  177. }
  178. if (query.Filters != null)
  179. {
  180. dict.Add("Filters", query.Filters.Select(f => f.ToString()));
  181. }
  182. if (query.ImageTypes != null)
  183. {
  184. dict.Add("ImageTypes", query.ImageTypes.Select(f => f.ToString()));
  185. }
  186. dict.Add("recursive", query.Recursive);
  187. dict.AddIfNotNull("genres", query.Genres);
  188. dict.AddIfNotNull("studios", query.Studios);
  189. dict.AddIfNotNull("ExcludeItemTypes", query.ExcludeItemTypes);
  190. dict.AddIfNotNull("IncludeItemTypes", query.IncludeItemTypes);
  191. dict.AddIfNotNullOrEmpty("person", query.Person);
  192. dict.AddIfNotNullOrEmpty("personType", query.PersonType);
  193. dict.AddIfNotNull("years", query.Years);
  194. dict.AddIfNotNullOrEmpty("indexBy", query.IndexBy);
  195. dict.AddIfNotNullOrEmpty("dynamicSortBy", query.DynamicSortBy);
  196. dict.AddIfNotNullOrEmpty("SearchTerm", query.SearchTerm);
  197. return GetApiUrl("Users/" + query.UserId + "/Items", dict);
  198. }
  199. /// <summary>
  200. /// Gets the image URL.
  201. /// </summary>
  202. /// <param name="baseUrl">The base URL.</param>
  203. /// <param name="options">The options.</param>
  204. /// <param name="queryParams">The query params.</param>
  205. /// <returns>System.String.</returns>
  206. /// <exception cref="System.ArgumentNullException">options</exception>
  207. private string GetImageUrl(string baseUrl, ImageOptions options, QueryStringDictionary queryParams)
  208. {
  209. if (options == null)
  210. {
  211. throw new ArgumentNullException("options");
  212. }
  213. if (queryParams == null)
  214. {
  215. throw new ArgumentNullException("queryParams");
  216. }
  217. if (options.ImageIndex.HasValue)
  218. {
  219. baseUrl += "/" + options.ImageIndex.Value;
  220. }
  221. queryParams.AddIfNotNull("width", options.Width);
  222. queryParams.AddIfNotNull("height", options.Height);
  223. queryParams.AddIfNotNull("maxWidth", options.MaxWidth);
  224. queryParams.AddIfNotNull("maxHeight", options.MaxHeight);
  225. queryParams.AddIfNotNull("Quality", options.Quality);
  226. queryParams.AddIfNotNull("tag", options.Tag);
  227. return GetApiUrl(baseUrl, queryParams);
  228. }
  229. /// <summary>
  230. /// Gets the image URL.
  231. /// </summary>
  232. /// <param name="item">The item.</param>
  233. /// <param name="options">The options.</param>
  234. /// <returns>System.String.</returns>
  235. /// <exception cref="System.ArgumentNullException">item</exception>
  236. public string GetImageUrl(BaseItemDto item, ImageOptions options)
  237. {
  238. if (item == null)
  239. {
  240. throw new ArgumentNullException("item");
  241. }
  242. if (options == null)
  243. {
  244. throw new ArgumentNullException("options");
  245. }
  246. var index = options.ImageIndex ?? 0;
  247. if (options.ImageType == ImageType.Backdrop)
  248. {
  249. options.Tag = item.BackdropImageTags[index];
  250. }
  251. else if (options.ImageType == ImageType.ChapterImage)
  252. {
  253. options.Tag = item.Chapters[index].ImageTag;
  254. }
  255. else
  256. {
  257. options.Tag = item.ImageTags[options.ImageType];
  258. }
  259. return GetImageUrl(item.Id, options);
  260. }
  261. /// <summary>
  262. /// Gets an image url that can be used to download an image from the api
  263. /// </summary>
  264. /// <param name="itemId">The Id of the item</param>
  265. /// <param name="options">The options.</param>
  266. /// <returns>System.String.</returns>
  267. /// <exception cref="System.ArgumentNullException">itemId</exception>
  268. public string GetImageUrl(string itemId, ImageOptions options)
  269. {
  270. if (string.IsNullOrEmpty(itemId))
  271. {
  272. throw new ArgumentNullException("itemId");
  273. }
  274. var url = "Items/" + itemId + "/Images/" + options.ImageType;
  275. return GetImageUrl(url, options, new QueryStringDictionary());
  276. }
  277. /// <summary>
  278. /// Gets the user image URL.
  279. /// </summary>
  280. /// <param name="user">The user.</param>
  281. /// <param name="options">The options.</param>
  282. /// <returns>System.String.</returns>
  283. /// <exception cref="System.ArgumentNullException">user</exception>
  284. public string GetUserImageUrl(UserDto user, ImageOptions options)
  285. {
  286. if (user == null)
  287. {
  288. throw new ArgumentNullException("user");
  289. }
  290. if (options == null)
  291. {
  292. throw new ArgumentNullException("options");
  293. }
  294. options.Tag = user.PrimaryImageTag;
  295. return GetUserImageUrl(user.Id, options);
  296. }
  297. /// <summary>
  298. /// Gets an image url that can be used to download an image from the api
  299. /// </summary>
  300. /// <param name="userId">The Id of the user</param>
  301. /// <param name="options">The options.</param>
  302. /// <returns>System.String.</returns>
  303. /// <exception cref="System.ArgumentNullException">userId</exception>
  304. public string GetUserImageUrl(Guid userId, ImageOptions options)
  305. {
  306. if (userId == Guid.Empty)
  307. {
  308. throw new ArgumentNullException("userId");
  309. }
  310. var url = "Users/" + userId + "/Images/" + options.ImageType;
  311. return GetImageUrl(url, options, new QueryStringDictionary());
  312. }
  313. /// <summary>
  314. /// Gets the person image URL.
  315. /// </summary>
  316. /// <param name="item">The item.</param>
  317. /// <param name="options">The options.</param>
  318. /// <returns>System.String.</returns>
  319. /// <exception cref="System.ArgumentNullException">item</exception>
  320. public string GetPersonImageUrl(BaseItemPerson item, ImageOptions options)
  321. {
  322. if (item == null)
  323. {
  324. throw new ArgumentNullException("item");
  325. }
  326. if (options == null)
  327. {
  328. throw new ArgumentNullException("options");
  329. }
  330. options.Tag = item.PrimaryImageTag;
  331. return GetPersonImageUrl(item.Name, options);
  332. }
  333. /// <summary>
  334. /// Gets the person image URL.
  335. /// </summary>
  336. /// <param name="item">The item.</param>
  337. /// <param name="options">The options.</param>
  338. /// <returns>System.String.</returns>
  339. /// <exception cref="System.ArgumentNullException">item</exception>
  340. public string GetPersonImageUrl(BaseItemDto item, ImageOptions options)
  341. {
  342. if (item == null)
  343. {
  344. throw new ArgumentNullException("item");
  345. }
  346. if (options == null)
  347. {
  348. throw new ArgumentNullException("options");
  349. }
  350. options.Tag = item.ImageTags[ImageType.Primary];
  351. return GetPersonImageUrl(item.Name, options);
  352. }
  353. /// <summary>
  354. /// Gets an image url that can be used to download an image from the api
  355. /// </summary>
  356. /// <param name="name">The name of the person</param>
  357. /// <param name="options">The options.</param>
  358. /// <returns>System.String.</returns>
  359. /// <exception cref="System.ArgumentNullException">name</exception>
  360. public string GetPersonImageUrl(string name, ImageOptions options)
  361. {
  362. if (string.IsNullOrEmpty(name))
  363. {
  364. throw new ArgumentNullException("name");
  365. }
  366. var url = "Persons/" + name + "/Images/" + options.ImageType;
  367. return GetImageUrl(url, options, new QueryStringDictionary());
  368. }
  369. /// <summary>
  370. /// Gets the year image URL.
  371. /// </summary>
  372. /// <param name="item">The item.</param>
  373. /// <param name="options">The options.</param>
  374. /// <returns>System.String.</returns>
  375. /// <exception cref="System.ArgumentNullException">item</exception>
  376. public string GetYearImageUrl(BaseItemDto item, ImageOptions options)
  377. {
  378. if (item == null)
  379. {
  380. throw new ArgumentNullException("item");
  381. }
  382. if (options == null)
  383. {
  384. throw new ArgumentNullException("options");
  385. }
  386. options.Tag = item.ImageTags[ImageType.Primary];
  387. return GetYearImageUrl(int.Parse(item.Name), options);
  388. }
  389. /// <summary>
  390. /// Gets an image url that can be used to download an image from the api
  391. /// </summary>
  392. /// <param name="year">The year.</param>
  393. /// <param name="options">The options.</param>
  394. /// <returns>System.String.</returns>
  395. public string GetYearImageUrl(int year, ImageOptions options)
  396. {
  397. var url = "Years/" + year + "/Images/" + options.ImageType;
  398. return GetImageUrl(url, options, new QueryStringDictionary());
  399. }
  400. /// <summary>
  401. /// Gets the genre image URL.
  402. /// </summary>
  403. /// <param name="item">The item.</param>
  404. /// <param name="options">The options.</param>
  405. /// <returns>System.String.</returns>
  406. /// <exception cref="System.ArgumentNullException">item</exception>
  407. public string GetGenreImageUrl(BaseItemDto item, ImageOptions options)
  408. {
  409. if (item == null)
  410. {
  411. throw new ArgumentNullException("item");
  412. }
  413. if (options == null)
  414. {
  415. throw new ArgumentNullException("options");
  416. }
  417. options.Tag = item.ImageTags[ImageType.Primary];
  418. return GetGenreImageUrl(item.Name, options);
  419. }
  420. /// <summary>
  421. /// Gets an image url that can be used to download an image from the api
  422. /// </summary>
  423. /// <param name="name">The name.</param>
  424. /// <param name="options">The options.</param>
  425. /// <returns>System.String.</returns>
  426. /// <exception cref="System.ArgumentNullException">name</exception>
  427. public string GetGenreImageUrl(string name, ImageOptions options)
  428. {
  429. if (string.IsNullOrEmpty(name))
  430. {
  431. throw new ArgumentNullException("name");
  432. }
  433. var url = "Genres/" + name + "/Images/" + options.ImageType;
  434. return GetImageUrl(url, options, new QueryStringDictionary());
  435. }
  436. /// <summary>
  437. /// Gets the studio image URL.
  438. /// </summary>
  439. /// <param name="item">The item.</param>
  440. /// <param name="options">The options.</param>
  441. /// <returns>System.String.</returns>
  442. /// <exception cref="System.ArgumentNullException">item</exception>
  443. public string GetStudioImageUrl(BaseItemDto item, ImageOptions options)
  444. {
  445. if (item == null)
  446. {
  447. throw new ArgumentNullException("item");
  448. }
  449. if (options == null)
  450. {
  451. throw new ArgumentNullException("options");
  452. }
  453. options.Tag = item.ImageTags[ImageType.Primary];
  454. return GetStudioImageUrl(item.Name, options);
  455. }
  456. /// <summary>
  457. /// Gets an image url that can be used to download an image from the api
  458. /// </summary>
  459. /// <param name="name">The name.</param>
  460. /// <param name="options">The options.</param>
  461. /// <returns>System.String.</returns>
  462. /// <exception cref="System.ArgumentNullException">name</exception>
  463. public string GetStudioImageUrl(string name, ImageOptions options)
  464. {
  465. if (string.IsNullOrEmpty(name))
  466. {
  467. throw new ArgumentNullException("name");
  468. }
  469. var url = "Studios/" + name + "/Images/" + options.ImageType;
  470. return GetImageUrl(url, options, new QueryStringDictionary());
  471. }
  472. /// <summary>
  473. /// 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.
  474. /// </summary>
  475. /// <param name="item">A given item.</param>
  476. /// <param name="options">The options.</param>
  477. /// <returns>System.String[][].</returns>
  478. /// <exception cref="System.ArgumentNullException">item</exception>
  479. public string[] GetBackdropImageUrls(BaseItemDto item, ImageOptions options)
  480. {
  481. if (item == null)
  482. {
  483. throw new ArgumentNullException("item");
  484. }
  485. if (options == null)
  486. {
  487. throw new ArgumentNullException("options");
  488. }
  489. options.ImageType = ImageType.Backdrop;
  490. string backdropItemId;
  491. List<Guid> backdropImageTags;
  492. if (item.BackdropCount == 0)
  493. {
  494. backdropItemId = item.ParentBackdropItemId;
  495. backdropImageTags = item.ParentBackdropImageTags;
  496. }
  497. else
  498. {
  499. backdropItemId = item.Id;
  500. backdropImageTags = item.BackdropImageTags;
  501. }
  502. if (string.IsNullOrEmpty(backdropItemId))
  503. {
  504. return new string[] { };
  505. }
  506. var files = new string[backdropImageTags.Count];
  507. for (var i = 0; i < backdropImageTags.Count; i++)
  508. {
  509. options.ImageIndex = i;
  510. options.Tag = backdropImageTags[i];
  511. files[i] = GetImageUrl(backdropItemId, options);
  512. }
  513. return files;
  514. }
  515. /// <summary>
  516. /// This is a helper to get the logo image url from a given ApiBaseItemWrapper. If the actual item does not have a logo, it will return the logo from the first parent that does, or null.
  517. /// </summary>
  518. /// <param name="item">A given item.</param>
  519. /// <param name="options">The options.</param>
  520. /// <returns>System.String.</returns>
  521. /// <exception cref="System.ArgumentNullException">item</exception>
  522. public string GetLogoImageUrl(BaseItemDto item, ImageOptions options)
  523. {
  524. if (item == null)
  525. {
  526. throw new ArgumentNullException("item");
  527. }
  528. if (options == null)
  529. {
  530. throw new ArgumentNullException("options");
  531. }
  532. options.ImageType = ImageType.Logo;
  533. var logoItemId = item.HasLogo ? item.Id : item.ParentLogoItemId;
  534. var imageTag = item.HasLogo ? item.ImageTags[ImageType.Logo] : item.ParentLogoImageTag;
  535. if (!string.IsNullOrEmpty(logoItemId))
  536. {
  537. options.Tag = imageTag;
  538. return GetImageUrl(logoItemId, options);
  539. }
  540. return null;
  541. }
  542. /// <summary>
  543. /// Gets the url needed to stream an audio file
  544. /// </summary>
  545. /// <param name="options">The options.</param>
  546. /// <returns>System.String.</returns>
  547. /// <exception cref="System.ArgumentNullException">options</exception>
  548. public string GetAudioStreamUrl(StreamOptions options)
  549. {
  550. if (options == null)
  551. {
  552. throw new ArgumentNullException("options");
  553. }
  554. var handler = "audio." + options.OutputFileExtension.TrimStart('.');
  555. return GetMediaStreamUrl(handler, options, new QueryStringDictionary());
  556. }
  557. /// <summary>
  558. /// Gets the url needed to stream a video file
  559. /// </summary>
  560. /// <param name="options">The options.</param>
  561. /// <returns>System.String.</returns>
  562. /// <exception cref="System.ArgumentNullException">options</exception>
  563. public string GetVideoStreamUrl(VideoStreamOptions options)
  564. {
  565. if (options == null)
  566. {
  567. throw new ArgumentNullException("options");
  568. }
  569. var handler = "video." + options.OutputFileExtension.TrimStart('.');
  570. return GetVideoStreamUrl(handler, options);
  571. }
  572. /// <summary>
  573. /// Formulates a url for streaming audio using the HLS protocol
  574. /// </summary>
  575. /// <param name="options">The options.</param>
  576. /// <returns>System.String.</returns>
  577. /// <exception cref="System.ArgumentNullException">options</exception>
  578. public string GetHlsAudioStreamUrl(StreamOptions options)
  579. {
  580. if (options == null)
  581. {
  582. throw new ArgumentNullException("options");
  583. }
  584. return GetMediaStreamUrl("audio.m3u8", options, new QueryStringDictionary());
  585. }
  586. /// <summary>
  587. /// Formulates a url for streaming video using the HLS protocol
  588. /// </summary>
  589. /// <param name="options">The options.</param>
  590. /// <returns>System.String.</returns>
  591. /// <exception cref="System.ArgumentNullException">options</exception>
  592. public string GetHlsVideoStreamUrl(VideoStreamOptions options)
  593. {
  594. if (options == null)
  595. {
  596. throw new ArgumentNullException("options");
  597. }
  598. return GetVideoStreamUrl("video.m3u8", options);
  599. }
  600. /// <summary>
  601. /// Gets the video stream URL.
  602. /// </summary>
  603. /// <param name="handler">The handler.</param>
  604. /// <param name="options">The options.</param>
  605. /// <returns>System.String.</returns>
  606. private string GetVideoStreamUrl(string handler, VideoStreamOptions options)
  607. {
  608. var queryParams = new QueryStringDictionary();
  609. if (options.VideoCodec.HasValue)
  610. {
  611. queryParams["VideoCodec"] = options.VideoCodec.Value.ToString();
  612. }
  613. queryParams.AddIfNotNull("VideoBitRate", options.VideoBitRate);
  614. queryParams.AddIfNotNull("Width", options.Width);
  615. queryParams.AddIfNotNull("Height", options.Height);
  616. queryParams.AddIfNotNull("MaxWidth", options.MaxWidth);
  617. queryParams.AddIfNotNull("MaxHeight", options.MaxHeight);
  618. queryParams.AddIfNotNull("FrameRate", options.FrameRate);
  619. queryParams.AddIfNotNull("AudioStreamIndex", options.AudioStreamIndex);
  620. queryParams.AddIfNotNull("VideoStreamIndex", options.VideoStreamIndex);
  621. queryParams.AddIfNotNull("SubtitleStreamIndex", options.SubtitleStreamIndex);
  622. return GetMediaStreamUrl(handler, options, queryParams);
  623. }
  624. /// <summary>
  625. /// Gets the media stream URL.
  626. /// </summary>
  627. /// <param name="handler">The handler.</param>
  628. /// <param name="options">The options.</param>
  629. /// <param name="queryParams">The query params.</param>
  630. /// <returns>System.String.</returns>
  631. /// <exception cref="System.ArgumentNullException">handler</exception>
  632. private string GetMediaStreamUrl(string handler, StreamOptions options, QueryStringDictionary queryParams)
  633. {
  634. if (string.IsNullOrEmpty(handler))
  635. {
  636. throw new ArgumentNullException("handler");
  637. }
  638. if (options == null)
  639. {
  640. throw new ArgumentNullException("options");
  641. }
  642. if (queryParams == null)
  643. {
  644. throw new ArgumentNullException("queryParams");
  645. }
  646. queryParams.Add("id", options.ItemId);
  647. if (options.AudioCodec.HasValue)
  648. {
  649. queryParams["audioCodec"] = options.AudioCodec.Value.ToString();
  650. }
  651. queryParams.AddIfNotNull("audiochannels", options.MaxAudioChannels);
  652. queryParams.AddIfNotNull("audiosamplerate", options.MaxAudioSampleRate);
  653. queryParams.AddIfNotNull("AudioBitRate", options.AudioBitRate);
  654. queryParams.AddIfNotNull("StartTimeTicks", options.StartTimeTicks);
  655. queryParams.AddIfNotNull("Static", options.Static);
  656. return GetApiUrl(handler, queryParams);
  657. }
  658. /// <summary>
  659. /// Deserializes from stream.
  660. /// </summary>
  661. /// <typeparam name="T"></typeparam>
  662. /// <param name="stream">The stream.</param>
  663. /// <returns>``0.</returns>
  664. protected T DeserializeFromStream<T>(Stream stream)
  665. where T : class
  666. {
  667. return (T)DataSerializer.DeserializeFromStream(stream, SerializationFormat, typeof(T));
  668. }
  669. /// <summary>
  670. /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
  671. /// </summary>
  672. public void Dispose()
  673. {
  674. Dispose(true);
  675. GC.SuppressFinalize(this);
  676. }
  677. /// <summary>
  678. /// Releases unmanaged and - optionally - managed resources.
  679. /// </summary>
  680. /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
  681. protected virtual void Dispose(bool disposing)
  682. {
  683. }
  684. }
  685. }