Source: lib/device/tizen.js

  1. /*! @license
  2. * Shaka Player
  3. * Copyright 2025 Google LLC
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. goog.provide('shaka.device.Tizen');
  7. goog.require('shaka.config.CrossBoundaryStrategy');
  8. goog.require('shaka.device.AbstractDevice');
  9. goog.require('shaka.device.DeviceFactory');
  10. goog.require('shaka.device.IDevice');
  11. goog.require('shaka.log');
  12. /**
  13. * @final
  14. */
  15. shaka.device.Tizen = class extends shaka.device.AbstractDevice {
  16. constructor() {
  17. super();
  18. const match = navigator.userAgent.match(/Tizen (\d+).(\d+)/);
  19. /** @private {?number} */
  20. this.osMajorVersion_ = match ? parseInt(match[1], 10) : null;
  21. /** @private {?number} */
  22. this.osMinorVersion_ = match ? parseInt(match[2], 10) : null;
  23. }
  24. /**
  25. * @override
  26. */
  27. getVersion() {
  28. return this.osMajorVersion_;
  29. }
  30. /**
  31. * @override
  32. */
  33. getDeviceName() {
  34. return 'Tizen';
  35. }
  36. /**
  37. * @override
  38. */
  39. getBrowserEngine() {
  40. return shaka.device.IDevice.BrowserEngine.CHROMIUM;
  41. }
  42. /**
  43. * @override
  44. */
  45. getDeviceType() {
  46. return shaka.device.IDevice.DeviceType.TV;
  47. }
  48. /**
  49. * @override
  50. */
  51. requiresEncryptionInfoInAllInitSegments(keySystem) {
  52. return true;
  53. }
  54. /**
  55. * @override
  56. */
  57. requiresEC3InitSegments() {
  58. return this.getVersion() === 3;
  59. }
  60. /**
  61. * @override
  62. */
  63. supportsMediaCapabilities() {
  64. return false;
  65. }
  66. /**
  67. * @override
  68. */
  69. supportsSequenceMode() {
  70. const version = this.getVersion();
  71. return version !== null ? version >= 4 : super.supportsSequenceMode();
  72. }
  73. /**
  74. * @override
  75. */
  76. supportsSmoothCodecSwitching() {
  77. return false;
  78. }
  79. /**
  80. * @override
  81. */
  82. supportsServerCertificate() {
  83. // Tizen 5.0 and earlier do not support server certificates.
  84. if (!this.osMajorVersion_ || !this.osMinorVersion_) {
  85. return super.supportsServerCertificate();
  86. }
  87. if (this.osMajorVersion_ === 5) {
  88. return this.osMinorVersion_ >= 5;
  89. }
  90. return this.osMajorVersion_ > 5;
  91. }
  92. /**
  93. * @override
  94. */
  95. detectMaxHardwareResolution() {
  96. const maxResolution = {width: 1920, height: 1080};
  97. try {
  98. if (webapis.systeminfo && webapis.systeminfo.getMaxVideoResolution) {
  99. const maxVideoResolution =
  100. webapis.systeminfo.getMaxVideoResolution();
  101. maxResolution.width = maxVideoResolution.width;
  102. maxResolution.height = maxVideoResolution.height;
  103. } else {
  104. if (webapis.productinfo.is8KPanelSupported &&
  105. webapis.productinfo.is8KPanelSupported()) {
  106. maxResolution.width = 7680;
  107. maxResolution.height = 4320;
  108. } else if (webapis.productinfo.isUdPanelSupported &&
  109. webapis.productinfo.isUdPanelSupported()) {
  110. maxResolution.width = 3840;
  111. maxResolution.height = 2160;
  112. }
  113. }
  114. } catch (e) {
  115. shaka.log.alwaysWarn('Tizen: Error detecting screen size, default ' +
  116. 'screen size 1920x1080.');
  117. }
  118. return Promise.resolve(maxResolution);
  119. }
  120. /**
  121. * @override
  122. */
  123. adjustConfig(config) {
  124. super.adjustConfig(config);
  125. config.drm.ignoreDuplicateInitData = this.getVersion() !== 2;
  126. if (this.getVersion() === 3) {
  127. config.streaming.crossBoundaryStrategy =
  128. shaka.config.CrossBoundaryStrategy.RESET;
  129. }
  130. config.streaming.shouldFixTimestampOffset = true;
  131. // Tizen has long hardware pipeline that respond slowly to seeking.
  132. // Therefore we should not seek when we detect a stall on this platform.
  133. // Instead, default stallSkip to 0 to force the stall detector to pause
  134. // and play instead.
  135. config.streaming.stallSkip = 0;
  136. config.streaming.gapPadding = 2;
  137. return config;
  138. }
  139. /**
  140. * @override
  141. */
  142. rejectCodecs() {
  143. // Tizen's implementation of MSE does not work well with opus. To prevent
  144. // the player from trying to play opus on Tizen, we will override media
  145. // source to always reject opus content.
  146. const codecs = [];
  147. if (this.osMajorVersion_ !== null && this.osMajorVersion_ < 5) {
  148. codecs.push('opus');
  149. }
  150. return codecs;
  151. }
  152. /**
  153. * @override
  154. */
  155. misreportAC3UsingDrm() {
  156. return true;
  157. }
  158. /**
  159. * @override
  160. */
  161. misreportsSupportForPersistentLicenses() {
  162. return this.getVersion() === 3;
  163. }
  164. /**
  165. * @return {boolean}
  166. * @private
  167. */
  168. static isTizen_() {
  169. return navigator.userAgent.includes('Tizen');
  170. }
  171. };
  172. if (shaka.device.Tizen.isTizen_()) {
  173. shaka.device.DeviceFactory.registerDeviceFactory(
  174. () => new shaka.device.Tizen());
  175. }