Source: lib/hls/hls_classes.js

  1. /**
  2. * @license
  3. * Copyright 2016 Google Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. goog.provide('shaka.hls.Attribute');
  18. goog.provide('shaka.hls.Playlist');
  19. goog.provide('shaka.hls.PlaylistType');
  20. goog.provide('shaka.hls.Segment');
  21. goog.provide('shaka.hls.Tag');
  22. goog.require('goog.asserts');
  23. /**
  24. * Creates an HLS playlist object.
  25. *
  26. * @param {string} absoluteUri An absolute, final URI after redirects.
  27. * @param {!shaka.hls.PlaylistType} type
  28. * @param {!Array.<shaka.hls.Tag>} tags
  29. * @param {!Array.<shaka.hls.Segment>=} opt_segments
  30. *
  31. * @constructor
  32. * @struct
  33. */
  34. shaka.hls.Playlist = function(absoluteUri, type, tags, opt_segments) {
  35. /**
  36. * An absolute, final URI after redirects.
  37. *
  38. * @const {string}
  39. */
  40. this.absoluteUri = absoluteUri;
  41. /** @const {shaka.hls.PlaylistType} */
  42. this.type = type;
  43. /** @const {!Array.<!shaka.hls.Tag>} */
  44. this.tags = tags;
  45. /** @const {Array.<!shaka.hls.Segment>} */
  46. this.segments = opt_segments || null;
  47. };
  48. /**
  49. * @enum {number}
  50. */
  51. shaka.hls.PlaylistType = {
  52. MASTER: 0,
  53. MEDIA: 1
  54. };
  55. /**
  56. * Creates an HLS tag object.
  57. *
  58. * @param {number} id
  59. * @param {string} name
  60. * @param {!Array.<shaka.hls.Attribute>} attributes
  61. * @param {?string=} opt_value
  62. *
  63. * @constructor
  64. * @struct
  65. */
  66. shaka.hls.Tag = function(id, name, attributes, opt_value) {
  67. goog.asserts.assert(
  68. (attributes.length == 0 && opt_value) ||
  69. (attributes.length > 0 && !opt_value) ||
  70. (attributes.length == 0 && !opt_value),
  71. 'Tags can only take the form ' +
  72. '(1) <NAME>:<VALUE> ' +
  73. '(2) <NAME>:<ATTRIBUTE_LIST> ' +
  74. ' (3) <NAME>');
  75. /** @const {number} */
  76. this.id = id;
  77. /** @const {string} */
  78. this.name = name;
  79. /** @const {Array.<shaka.hls.Attribute>} */
  80. this.attributes = attributes;
  81. /** @const {?string} */
  82. this.value = opt_value || null;
  83. };
  84. /**
  85. * Create the string representation of the tag.
  86. *
  87. * For the DRM system - the full tag needs to be passed down to the CDM. There
  88. * are two ways of doing this (1) save the original tag or (2) recreate the tag.
  89. * As in some cases (like in tests) the tag never existed in string form, it
  90. * is far easier to recreate the tag from the parsed form.
  91. *
  92. * @return {string}
  93. * @override
  94. */
  95. shaka.hls.Tag.prototype.toString = function() {
  96. /**
  97. * @param {shaka.hls.Attribute} attr
  98. * @return {string}
  99. */
  100. let attrToStr = function(attr) {
  101. return attr.name + '="' + attr.value + '"';
  102. };
  103. // A valid tag can only follow 1 of 3 patterns.
  104. // 1) <NAME>:<VALUE>
  105. // 2) <NAME>:<ATTRIBUTE LIST>
  106. // 3) <NAME>
  107. if (this.value) {
  108. return '#' + this.name + ':' + this.value;
  109. }
  110. if (this.attributes.length > 0) {
  111. return '#' + this.name + ':' + this.attributes.map(attrToStr).join(',');
  112. }
  113. return '#' + this.name;
  114. };
  115. /**
  116. * Creates an HLS attribute object.
  117. *
  118. * @param {string} name
  119. * @param {string} value
  120. *
  121. * @constructor
  122. * @struct
  123. */
  124. shaka.hls.Attribute = function(name, value) {
  125. /** @const {string} */
  126. this.name = name;
  127. /** @const {string} */
  128. this.value = value;
  129. };
  130. /**
  131. * Adds an attribute to an HLS Tag.
  132. *
  133. * @param {!shaka.hls.Attribute} attribute
  134. */
  135. shaka.hls.Tag.prototype.addAttribute = function(attribute) {
  136. this.attributes.push(attribute);
  137. };
  138. /**
  139. * Gets the first attribute of the tag with a specified name.
  140. *
  141. * @param {string} name
  142. * @return {?shaka.hls.Attribute} attribute
  143. */
  144. shaka.hls.Tag.prototype.getAttribute = function(name) {
  145. let attributes = this.attributes.filter(function(attr) {
  146. return attr.name == name;
  147. });
  148. goog.asserts.assert(attributes.length < 2,
  149. 'A tag should not have multiple attributes ' +
  150. 'with the same name!');
  151. if (attributes.length) {
  152. return attributes[0];
  153. } else {
  154. return null;
  155. }
  156. };
  157. /**
  158. * Gets the value of the first attribute of the tag with a specified name.
  159. * If not found, returns an optional default value.
  160. *
  161. * @param {string} name
  162. * @param {string=} opt_defaultValue
  163. * @return {?string}
  164. */
  165. shaka.hls.Tag.prototype.getAttributeValue = function(name, opt_defaultValue) {
  166. let defaultValue = opt_defaultValue || null;
  167. let attribute = this.getAttribute(name);
  168. return attribute ? attribute.value : defaultValue;
  169. };
  170. /**
  171. * Creates an HLS segment object.
  172. *
  173. * @param {string} absoluteUri An absolute URI.
  174. * @param {!Array.<shaka.hls.Tag>} tags
  175. *
  176. * @constructor
  177. * @struct
  178. */
  179. shaka.hls.Segment = function(absoluteUri, tags) {
  180. /** @const {!Array.<shaka.hls.Tag>} */
  181. this.tags = tags;
  182. /**
  183. * An absolute URI.
  184. *
  185. * @const {string}
  186. */
  187. this.absoluteUri = absoluteUri;
  188. };