BaseApiClient.cs 29 KB

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