@24i/smartapps-bigscreen-rnv-build-engine 0.17.6-alpha.9 → 0.17.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +16 -12
  2. package/dist/src/constants/buildProductionPackages.js +1 -0
  3. package/dist/src/constants/delopyLivePlatforms.js +2 -1
  4. package/dist/src/constants/platforms.js +2 -0
  5. package/dist/src/engine.js +10 -0
  6. package/dist/src/resolvers/index.js +3 -1
  7. package/dist/src/resolvers/resolveBaseUrl.js +5 -24
  8. package/dist/src/resolvers/resolveProductionZipFileRelativePath.js +1 -2
  9. package/dist/src/resolvers/resolveS3BucketAppPath.js +15 -0
  10. package/dist/src/resolvers/shared/constructFullUrl.js +25 -0
  11. package/dist/src/scripts/buildAllWithSchemes.js +23 -4
  12. package/dist/src/scripts/release/appCenter/deployProductionPackagesToAppCenter.js +20 -10
  13. package/dist/src/scripts/release/urlsMarkdown.js +2 -0
  14. package/dist/src/sdks/index.js +1 -0
  15. package/dist/src/sdks/sdk-androidtv/sdkAndroidtv.js +25 -9
  16. package/dist/src/sdks/sdk-tizen/sdkTizen.js +2 -0
  17. package/dist/src/sdks/sdk-webos/sdkWebos.js +2 -0
  18. package/dist/src/sdks/sdk-webpack/sdkWebpack.js +2 -0
  19. package/dist/src/tasks/deploy/aswS3/deployS3.js +3 -10
  20. package/dist/src/tasks/deploy/aswS3/distToLiveS3.js +4 -5
  21. package/dist/src/tasks/deploy/hbbtv/deployHbbtv.js +1 -1
  22. package/dist/src/tasks/task.rnv.build.js +16 -6
  23. package/dist/src/tasks/task.rnv.configure.js +2 -0
  24. package/dist/src/tasks/task.rnv.deploy.js +2 -0
  25. package/dist/src/tasks/task.rnv.platform.configure.js +33 -1
  26. package/dist/src/tasks/task.rnv.start.js +2 -0
  27. package/dist/src/utils/copyTheoPlayerLibs.js +48 -0
  28. package/dist/src/utils/zipStagingProdBuildsByPlatforms.js +3 -3
  29. package/dist/templates/platforms/androidtv/project/amazoniap/build.gradle +2 -2
  30. package/dist/templates/platforms/androidtv/project/app/build.gradle +17 -21
  31. package/dist/templates/platforms/androidtv/project/app/proguard-rules.pro +15 -0
  32. package/dist/templates/platforms/androidtv/project/app/src/bigscreenAppstage/res/raw/configuration.json +1 -2
  33. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/bridge/BridgeFromJavaScript.kt +4 -58
  34. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/bridge/BridgeToJavaScript.kt +15 -0
  35. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/configuration/BridgeConfig.kt +2 -1
  36. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/di/ActivityModule.kt +0 -3
  37. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/di/ApplicationModule.kt +2 -2
  38. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/di/PerActivity.kt +0 -0
  39. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/utils/PlayerFactoryConfigured.kt +33 -0
  40. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/utils/PlayerFactoryExoPlayerCustomized.kt +7 -1
  41. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/utils/PlayerFactoryTheoPlayerCustomized.kt +14 -0
  42. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/utils/PlayerFactoryVersion.kt +27 -0
  43. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/utils/SourceDrmOverridden.kt +42 -0
  44. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/model/MediaEventType.kt +3 -0
  45. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/parser/SourceParser.kt +89 -0
  46. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/view/Mainview.kt +0 -3
  47. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/view/PlayerCache.kt +2 -2
  48. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/view/WebViewActivity.kt +24 -83
  49. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/viewmodel/WebViewModel.kt +48 -111
  50. package/dist/templates/platforms/androidtv/project/app/src/main/res/layout/activity_web_view.xml +23 -71
  51. package/dist/templates/platforms/androidtv/project/common/build.gradle +2 -2
  52. package/dist/templates/platforms/androidtv/project/googleiap/build.gradle +2 -2
  53. package/package.json +1 -1
  54. package/renative.engine.json +2 -0
  55. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/jump/JumpAnalytics.kt +0 -211
  56. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/parser/ContentModelParser.kt +0 -16
  57. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/parser/DeviceInfoParser.kt +0 -22
@@ -19,6 +19,7 @@ const configureFn = async (c, parentTask, originTask) => {
19
19
  case constants_1.Platforms.KREATV:
20
20
  case constants_1.Platforms.SAPHI:
21
21
  case constants_1.Platforms.VIDAA:
22
+ case constants_1.Platforms.SMARTCAST:
22
23
  case constants_1.Platforms.WEBTV:
23
24
  case constants_1.Platforms.XBOX:
24
25
  await sdks_1.SDKWebpack.configureWebProject(c);
@@ -30,6 +31,7 @@ const configureFn = async (c, parentTask, originTask) => {
30
31
  await sdks_1.SDKWebos.configureWebOSProject(c);
31
32
  break;
32
33
  case constants_1.Platforms.ANDROIDTV:
34
+ case constants_1.Platforms.FIRETV:
33
35
  await sdks_1.SDKAndroidtv.configureAndroidTVProject(c);
34
36
  break;
35
37
  default:
@@ -28,8 +28,10 @@ const deployFn = async (c, parentTask, originTask) => {
28
28
  break;
29
29
  case constants_1.Platforms.ANDROIDTV:
30
30
  case constants_1.Platforms.ENTONE:
31
+ case constants_1.Platforms.FIRETV:
31
32
  case constants_1.Platforms.KREATV:
32
33
  case constants_1.Platforms.SAPHI:
34
+ case constants_1.Platforms.SMARTCAST:
33
35
  case constants_1.Platforms.TIZEN:
34
36
  case constants_1.Platforms.VIDAA:
35
37
  case constants_1.Platforms.WEBOS:
@@ -1,6 +1,30 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
26
  exports.customRnvPlatformConfigureTask = void 0;
27
+ const path = __importStar(require("path"));
4
28
  const rnv_1 = require("rnv");
5
29
  const schemeParser_1 = require("rnv/dist/core/configManager/schemeParser");
6
30
  const packageParser_1 = require("rnv/dist/core/configManager/packageParser");
@@ -14,7 +38,8 @@ const taskRnvPlatformConfigure = async (c, parentTask, originTask) => {
14
38
  await rnv_1.TaskManager.executeTask(c, TASK_PROJECT_CONFIGURE, TASK_PLATFORM_CONFIGURE, originTask);
15
39
  await rnv_1.PlatformManager.isPlatformSupported(c);
16
40
  await (0, schemeParser_1.isBuildSchemeSupported)(c);
17
- if (platform === constants_1.Platforms.ANDROIDTV) {
41
+ if (platform === constants_1.Platforms.ANDROIDTV ||
42
+ platform === constants_1.Platforms.FIRETV) {
18
43
  await (0, sdks_1.handlePlatformSdk)(c);
19
44
  }
20
45
  else {
@@ -34,6 +59,13 @@ const taskRnvPlatformConfigure = async (c, parentTask, originTask) => {
34
59
  await rnv_1.PlatformManager.cleanPlatformBuild(c, c.platform);
35
60
  }
36
61
  await rnv_1.PlatformManager.copySharedPlatforms(c);
62
+ if (platform === constants_1.Platforms.FIRETV) {
63
+ rnv_1.Logger.logInfo('We re-use AndroidTV template for FireTV platform!');
64
+ const templatesDir = c.paths.project.platformTemplatesDirs[platform];
65
+ const androidTvTemplateDir = path.join(templatesDir, constants_1.Platforms.ANDROIDTV);
66
+ const fireTvTemplateDir = path.join(templatesDir, constants_1.Platforms.FIRETV);
67
+ rnv_1.FileUtils.copyFolderContentsRecursiveSync(androidTvTemplateDir, fireTvTemplateDir);
68
+ }
37
69
  await rnv_1.PlatformManager.createPlatformBuild(c, c.platform);
38
70
  await (0, packageParser_1.injectPlatformDependencies)(c);
39
71
  };
@@ -19,11 +19,13 @@ const startFn = async (c, parentTask, originTask) => {
19
19
  switch (platform) {
20
20
  case constants_1.Platforms.ANDROIDTV:
21
21
  case constants_1.Platforms.ENTONE:
22
+ case constants_1.Platforms.FIRETV:
22
23
  case constants_1.Platforms.HBBTV:
23
24
  case constants_1.Platforms.KREATV:
24
25
  case constants_1.Platforms.SAPHI:
25
26
  case constants_1.Platforms.TIZEN:
26
27
  case constants_1.Platforms.VIDAA:
28
+ case constants_1.Platforms.SMARTCAST:
27
29
  case constants_1.Platforms.WEBOS:
28
30
  case constants_1.Platforms.WEBTV:
29
31
  case constants_1.Platforms.XBOX:
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.copyTheoPlayerLibs = void 0;
27
+ const path = __importStar(require("path"));
28
+ const fs = __importStar(require("fs"));
29
+ const fse = __importStar(require("fs-extra"));
30
+ const rnv_1 = require("rnv");
31
+ const copyTheoPlayerLibs = (c) => {
32
+ const theoplayerPackageDir = path.join(process.cwd(), 'node_modules', 'theoplayer');
33
+ if (!fs.existsSync(theoplayerPackageDir)) {
34
+ return;
35
+ }
36
+ const filesToCopy = [
37
+ 'THEOplayer.transmux.asmjs.js',
38
+ 'THEOplayer.transmux.js',
39
+ 'THEOplayer.transmux.wasm',
40
+ 'iframe.html'
41
+ ].map((fileName) => path.join(theoplayerPackageDir, fileName));
42
+ const buildProjectPublicDir = path.join(rnv_1.Common.getPlatformProjectDir(c), 'public', 'content');
43
+ filesToCopy.forEach((filePath) => {
44
+ const destFilePath = path.join(buildProjectPublicDir, 'theoplayer', path.basename(filePath));
45
+ fse.copySync(filePath, destFilePath);
46
+ });
47
+ };
48
+ exports.copyTheoPlayerLibs = copyTheoPlayerLibs;
@@ -42,8 +42,8 @@ const getPlatformBuildsPaths = (c, platformName, scheme) => {
42
42
  const platformBuildsGlob = `${outputGlob}/*.${(0, index_1.resolveBuildFileExtension)(platformName)}`;
43
43
  try {
44
44
  const buildsPathsCandidates = glob.sync(platformBuildsGlob) || [];
45
- const platformBuilsPaths = buildsPathsCandidates.filter((path) => path.includes(platformName));
46
- return platformBuilsPaths;
45
+ const platformBuildsPaths = buildsPathsCandidates.filter((path) => path.includes(platformName));
46
+ return platformBuildsPaths;
47
47
  }
48
48
  catch (e) {
49
49
  return [];
@@ -104,7 +104,7 @@ const processPlatform = (c, platformName, schemes) => {
104
104
  (0, fs_1.rmdirSync)(tempPlatformDir, { recursive: true });
105
105
  };
106
106
  const zipStagingProdBuildsByPlatforms = (c, schemes) => {
107
- const [stagingScheme, prodScheme] = schemes;
107
+ const [, prodScheme] = schemes;
108
108
  if (!prodScheme) {
109
109
  throw new Error('Missing production scheme.');
110
110
  }
@@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
2
2
  apply plugin: 'kotlin-android'
3
3
 
4
4
  android {
5
- compileSdkVersion 31
5
+ compileSdkVersion 33
6
6
 
7
7
  compileOptions {
8
8
  sourceCompatibility JavaVersion.VERSION_1_8
@@ -11,7 +11,7 @@ android {
11
11
 
12
12
  defaultConfig {
13
13
  minSdkVersion 21
14
- targetSdkVersion 30
14
+ targetSdkVersion 33
15
15
 
16
16
  versionCode 1
17
17
  versionName "1.0"
@@ -1,8 +1,9 @@
1
1
  apply plugin: 'com.android.application'
2
2
  apply plugin: 'kotlin-android'
3
3
  apply plugin: 'kotlin-kapt'
4
- apply plugin: 'com.google.gms.google-services'
5
- apply plugin: 'com.google.firebase.crashlytics'
4
+
5
+ def theoLicense = '{{THEO_LICENSE}}'
6
+ def useTheoPlayer = theoLicense != ''
6
7
 
7
8
  android {
8
9
  compileSdkVersion {{COMPILE_SDK_VERSION}}
@@ -32,6 +33,10 @@ android {
32
33
 
33
34
  // necessary for Fire OS - installation of debug build fails otherwise
34
35
  multiDexEnabled true
36
+
37
+ buildConfigField "String", "APP_URL", '"{{APP_URL}}"'
38
+ buildConfigField "String", "THEO_LICENSE", "\"$theoLicense\""
39
+ buildConfigField "Boolean", "startWithHighVideoQuality", "true"
35
40
  }
36
41
 
37
42
  signingConfigs {
@@ -40,8 +45,6 @@ android {
40
45
  keyPassword '{{KEY_PASSWORD}}'
41
46
  storeFile file('{{STORE_FILE}}')
42
47
  storePassword '{{STORE_PASSWORD}}'
43
- v1SigningEnabled true
44
- v2SigningEnabled true
45
48
  }
46
49
  }
47
50
 
@@ -57,7 +60,8 @@ android {
57
60
  }
58
61
 
59
62
  buildFeatures {
60
- dataBinding true
63
+ buildConfig true
64
+ viewBinding true
61
65
  }
62
66
 
63
67
  flavorDimensions "bridge"
@@ -74,16 +78,6 @@ android {
74
78
  }
75
79
  }
76
80
 
77
- //Enable GoogleServices and Crashlytics for specified variant
78
- android.applicationVariants.all { variant ->
79
- project.tasks.getByName('process' + variant.name.capitalize() + 'GoogleServices').enabled = false
80
- tasks.whenTaskAdded { task ->
81
- if (task.name.toLowerCase().contains("crashlytics")) {
82
- task.enabled = false
83
- }
84
- }
85
- }
86
-
87
81
  dependencies {
88
82
  implementation fileTree(include: ['*.jar'], dir: 'libs')
89
83
  implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
@@ -93,9 +87,6 @@ dependencies {
93
87
  compileOnly "javax.annotation:jsr250-api:1.0"
94
88
  implementation "androidx.appcompat:appcompat:1.4.2"
95
89
  implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
96
- implementation "androidx.recyclerview:recyclerview:1.2.1"
97
- implementation 'com.google.firebase:firebase-crashlytics:18.2.11'
98
- implementation 'com.google.firebase:firebase-analytics:21.0.0'
99
90
 
100
91
  implementation "com.google.dagger:dagger:2.42"
101
92
  kapt "com.google.dagger:dagger-compiler:2.42"
@@ -104,9 +95,14 @@ dependencies {
104
95
  implementation "com.squareup.retrofit2:converter-gson:2.5.0"
105
96
  implementation "com.squareup.okhttp3:logging-interceptor:4.9.2"
106
97
  implementation "com.squareup.okhttp3:okhttp:4.9.2"
107
- implementation "com.twentyfouri.player:exoplayer:0.6.0-alpha.23"
108
- implementation 'com.google.android.exoplayer:extension-okhttp:2.17.1'
109
- implementation "com.jumptvs.jumpkit:jumpkit-exoplayer:2.6.5"
98
+ if (useTheoPlayer) {
99
+ compileOnly "com.twentyfouri.player:exoplayer:0.6.0-alpha.36"
100
+ implementation "com.twentyfouri.player:theoplayer:0.6.0-alpha.36"
101
+ } else {
102
+ implementation "com.twentyfouri.player:exoplayer:0.6.0-alpha.36"
103
+ compileOnly "com.twentyfouri.player:theoplayer:0.6.0-alpha.36"
104
+ }
110
105
 
111
106
  implementation project(':common')
112
107
  }
108
+
@@ -29,4 +29,19 @@
29
29
  -keep class com.amazon.** {*;}
30
30
  -keepattributes *Annotation*
31
31
 
32
+ -keep class com.theoplayer.android.** {*;}
33
+ -dontwarn com.theoplayer.android.**
34
+ -keep public class com.google.android.gms.* { public *; }
35
+ -dontwarn com.google.android.gms.**
36
+
37
+ # In case of using yospace integration
38
+ -keep class com.yospace.util.** {*;}
39
+ -dontwarn com.yospace.util.**
40
+
41
+ # For native Google IMA integration
42
+ -keep class com.google.obf.** { *; }
43
+ -keep interface com.google.obf.** { *; }
44
+ -keep class com.google.ads.interactivemedia.** { *; }
45
+ -keep interface com.google.ads.interactivemedia.** { *; }
46
+
32
47
  -optimizationpasses 1
@@ -1,9 +1,8 @@
1
1
  {
2
- "baseUrl": "{{APP_URL}}",
3
2
  "customizableUrl": false,
4
3
  "mediaEventPrefix": "player:",
5
4
  "startWithHighVideoQuality": true,
6
5
  "drm": {
7
- "overrideDrmCallback": true
6
+ "overrideDrmCallback": false
8
7
  }
9
8
  }
@@ -8,8 +8,9 @@ import android.webkit.JavascriptInterface
8
8
  import com.google.gson.JsonObject
9
9
  import com.twentyfouri.player.base.TextTrack
10
10
  import com.twentyfouri.player.base.TrackKind
11
- import com.twentyfouri.tvbridge.webview.parser.ContentModelParser.stringToJson
11
+ import com.twentyfouri.tvbridge.webview.parser.SourceParser.stringToJson
12
12
  import com.twentyfouri.tvbridge.webview.parser.PlaybackInfoParser.parse
13
+ import com.twentyfouri.tvbridge.webview.parser.SourceParser
13
14
  import com.twentyfouri.tvbridge.webview.parser.TrackJsonModelParser.audioFromJson
14
15
  import com.twentyfouri.tvbridge.webview.parser.TrackJsonModelParser.textFromJson
15
16
  import com.twentyfouri.tvbridge.webview.parser.TrackJsonModelParser.toJson
@@ -69,19 +70,8 @@ class BridgeFromJavaScript(
69
70
  Log.d(LOG_TAG, "bridgeJavaScriptToAndroid_SetVideoPath = $jsonString")
70
71
  try {
71
72
  viewModel.stopPlayer()
72
- val contentModel = stringToJson(jsonString)
73
- contentModel?.streamType = mimeType?.let {
74
- when {
75
- mimeType.contains("application/dash+xml") -> "mpd"
76
- mimeType.contains("application/vnd.apple.mpegurl") -> "m3u8"
77
- mimeType.contains("video/mp4") -> "mp4"
78
- mimeType.contains("application/vnd.ms-sstr+xml") -> "ism"
79
- mimeType.contains("audio/mpeg") -> "mp3"
80
- else -> null
81
- }
82
- }
83
- if (contentModel?.streamUrl != null) {
84
- viewModel.setVideo(contentModel)
73
+ stringToJson(jsonString)?.also { source ->
74
+ viewModel.setVideo(source)
85
75
  }
86
76
  } catch (e: Exception) {
87
77
  Log.v(LOG_TAG, "bridgeJavaScriptToAndroid_SetVideoPathError - ${e.message}")
@@ -282,50 +272,6 @@ class BridgeFromJavaScript(
282
272
  viewModel.subtitleTrack?.let { toJson(it) } ?: DISABLED_SUBTITLE_TRACK
283
273
  }
284
274
 
285
- /*
286
- Returns VIDEO track BITRATE, if not available returns null
287
- */
288
- @JavascriptInterface
289
- fun bridgeJavaScriptToAndroid_GetBitrate(): Int? = runBlocking("bridgeJavaScriptToAndroid_GetBitrate") {
290
- viewModel.videoTrack?.bitrate
291
- }
292
-
293
- /*
294
- Returns VIDEO track RENDITION, if not available returns null
295
- */
296
- @JavascriptInterface
297
- fun bridgeJavaScriptToAndroid_GetRendition(): String? = runBlocking("bridgeJavaScriptToAndroid_GetRendition") {
298
- viewModel.videoTrack?.run {
299
- return@runBlocking "${width}x${height}${formatBitrate(bitrate)}"
300
- }
301
- null
302
- }
303
-
304
- private fun formatBitrate(bitrate: Int): String {
305
- return when {
306
- bitrate <= 0 -> ""
307
- bitrate < 1e3 -> "@${bitrate}bps"
308
- bitrate < 1e6 -> "@${(bitrate / 1e3).roundToInt()}Kbps"
309
- else -> "@${(bitrate / 1e4).roundToInt() / 1e2}Mbps"
310
- }
311
- }
312
-
313
- /*
314
- Returns AUDIO track CODEC, if not available returns null
315
- */
316
- @JavascriptInterface
317
- fun bridgeJavaScriptToAndroid_GetAudioCodec(): String? = runBlocking("bridgeJavaScriptToAndroid_GetAudioCodec") {
318
- viewModel.audioTrack?.codec
319
- }
320
-
321
- /*
322
- Returns VIDEO track CODEC, if not available returns null
323
- */
324
- @JavascriptInterface
325
- fun bridgeJavaScriptToAndroid_GetVideoCodec(): String? = runBlocking("bridgeJavaScriptToAndroid_GetVideoCodec") {
326
- viewModel.videoTrack?.codec
327
- }
328
-
329
275
  /*
330
276
  Set the cookies to localstorage
331
277
  */
@@ -2,10 +2,13 @@ package com.twentyfouri.tvbridge.bridge
2
2
 
3
3
  import android.util.Log
4
4
  import com.twentyfouri.player.base.AudioTrack
5
+ import com.twentyfouri.player.base.DefaultSourceSerializer
5
6
  import com.twentyfouri.player.base.TextTrack
7
+ import com.twentyfouri.player.base.TimelineEvent
6
8
  import com.twentyfouri.tvbridge.bridge.BridgeFromJavaScript.Companion.LOG_TAG
7
9
  import com.twentyfouri.tvbridge.configuration.BridgeConfig
8
10
  import com.twentyfouri.tvbridge.webview.parser.TrackJsonModelParser.toJson
11
+ import org.json.JSONArray
9
12
 
10
13
  class BridgeToJavaScript(
11
14
  config: BridgeConfig,
@@ -60,6 +63,18 @@ class BridgeToJavaScript(
60
63
  executeJavaScript(mediaEventString)
61
64
  }
62
65
 
66
+ fun bridgeAndroidToJavaScript_MediaAdBreaksEvent(
67
+ mediaEvent: String,
68
+ timeline: List<TimelineEvent>
69
+ ) {
70
+ val serializer = DefaultSourceSerializer()
71
+ val adsJson = JSONArray(timeline.map { serializer.toPersistentMap(it) }).toString()
72
+
73
+ val mediaEventString = "javascript:((function dispatchEvent(){var evt = document.createEvent('Events');evt.initEvent('$mediaEventPrefix$mediaEvent',true,true);evt.ads='$adsJson';document.dispatchEvent(evt);})())"
74
+ Log.v(LOG_TAG, mediaEventString)
75
+ executeJavaScript(mediaEventString)
76
+ }
77
+
63
78
  fun bridgeAndroidToJavaScript_IAPValidationError(message: String) {
64
79
  Log.d(LOG_TAG, "bridgeAndroidToJavaScript_IAPValidationError")
65
80
  executeJavaScript("javascript:((function dispatchEvent(){var evt = document.createEvent('Events');evt.initEvent('${iapEventPrefix}iapError',true,true);evt.message='$message';document.dispatchEvent(evt);})())")
@@ -3,7 +3,7 @@ package com.twentyfouri.tvbridge.configuration
3
3
  import com.twentyfouri.tvbridge.BuildConfig
4
4
 
5
5
  class BridgeConfig {
6
- var baseUrl: String = "http://portal.24imedia.tv/"
6
+ var baseUrl: String = BuildConfig.APP_URL
7
7
  var userAgent: UserAgent = UserAgent()
8
8
  var drm: Drm = Drm()
9
9
  var isEnabledTouchSound: Boolean = false
@@ -13,4 +13,5 @@ class BridgeConfig {
13
13
  var iapEventPrefix: String = ""
14
14
  var customizableUrl: Boolean = BuildConfig.DEBUG
15
15
  var startWithHighVideoQuality: Boolean = false
16
+ var theoLicense: String = BuildConfig.THEO_LICENSE
16
17
  }
@@ -1,9 +1,6 @@
1
1
  package com.twentyfouri.tvbridge.global.di
2
2
 
3
3
  import android.app.Activity
4
- import com.twentyfouri.player.base.PlayerFactoryBase
5
- import com.twentyfouri.tvbridge.configuration.BridgeConfig
6
- import com.twentyfouri.tvbridge.global.utils.PlayerFactoryExoPlayerCustomized
7
4
  import dagger.Module
8
5
  import dagger.Provides
9
6
 
@@ -7,7 +7,7 @@ import com.twentyfouri.tvbridge.common.NullIapService
7
7
  import com.twentyfouri.tvbridge.configuration.BridgeConfig
8
8
  import com.twentyfouri.tvbridge.global.BaseApplication
9
9
  import com.twentyfouri.tvbridge.global.utils.LocalStorage
10
- import com.twentyfouri.tvbridge.global.utils.PlayerFactoryExoPlayerCustomized
10
+ import com.twentyfouri.tvbridge.global.utils.PlayerFactoryConfigured
11
11
  import com.twentyfouri.tvbridge.sound.TouchPlayer
12
12
  import dagger.Module
13
13
  import dagger.Provides
@@ -46,6 +46,6 @@ class ApplicationModule(
46
46
  @Provides
47
47
  @Singleton
48
48
  fun providePlayerFactory(config: BridgeConfig): PlayerFactoryBase =
49
- PlayerFactoryExoPlayerCustomized(config)
49
+ PlayerFactoryConfigured.buildFactory(config)
50
50
 
51
51
  }
@@ -0,0 +1,33 @@
1
+ package com.twentyfouri.tvbridge.global.utils
2
+
3
+ import com.twentyfouri.player.base.*
4
+ import com.twentyfouri.player.theoplayer.PlayerFactoryTheoPlayer
5
+ import com.twentyfouri.tvbridge.configuration.BridgeConfig
6
+
7
+ object PlayerFactoryConfigured {
8
+
9
+ fun buildFactory(bridgeConfig: BridgeConfig): PlayerFactoryBase {
10
+ var factory: PlayerFactoryBase? = null
11
+ if (bridgeConfig.theoLicense.isNotEmpty()) {
12
+ factory = factory ?: buildTheoFactory(bridgeConfig)
13
+ }
14
+ factory = factory ?: buildExoFactory(bridgeConfig)
15
+ return factory ?: throw Exception("Cannot create player factory")
16
+ }
17
+
18
+ private fun buildExoFactory(bridgeConfig: BridgeConfig): PlayerFactoryBase? {
19
+ try {
20
+ return PlayerFactoryExoPlayerCustomized(bridgeConfig)
21
+ } catch (e: NoClassDefFoundError) {
22
+ return null
23
+ }
24
+ }
25
+
26
+ private fun buildTheoFactory(bridgeConfig: BridgeConfig): PlayerFactoryBase? {
27
+ try {
28
+ return PlayerFactoryTheoPlayerCustomized(bridgeConfig)
29
+ } catch (e: NoClassDefFoundError) {
30
+ return null
31
+ }
32
+ }
33
+ }
@@ -2,6 +2,7 @@ package com.twentyfouri.tvbridge.global.utils
2
2
 
3
3
  import android.content.Context
4
4
  import com.google.android.exoplayer2.C
5
+ import com.google.android.exoplayer2.ExoPlayerLibraryInfo
5
6
  import com.google.android.exoplayer2.drm.DefaultDrmSessionManager
6
7
  import com.google.android.exoplayer2.drm.DrmSessionManager
7
8
  import com.google.android.exoplayer2.drm.FrameworkMediaDrm
@@ -17,7 +18,12 @@ import com.twentyfouri.tvbridge.configuration.BridgeConfig
17
18
 
18
19
  class PlayerFactoryExoPlayerCustomized(
19
20
  private val config: BridgeConfig
20
- ) : PlayerFactoryExoPlayer() {
21
+ ) : PlayerFactoryExoPlayer(), PlayerFactoryVersion {
22
+
23
+ override val engineName: String = "Exoplayer"
24
+
25
+ override val engineVersion: String = ExoPlayerLibraryInfo.VERSION
26
+
21
27
  override fun createSharedComponents(context: Context): SharedComponents =
22
28
  CustomizedSharedComponents(context)
23
29
 
@@ -0,0 +1,14 @@
1
+ package com.twentyfouri.tvbridge.global.utils
2
+
3
+ import com.theoplayer.android.api.THEOplayerGlobal
4
+ import com.twentyfouri.player.theoplayer.PlayerFactoryTheoPlayer
5
+ import com.twentyfouri.tvbridge.configuration.BridgeConfig
6
+
7
+ class PlayerFactoryTheoPlayerCustomized(
8
+ private val config: BridgeConfig
9
+ ) : PlayerFactoryTheoPlayer(config.theoLicense), PlayerFactoryVersion {
10
+
11
+ override val engineName: String = "THEOPlayer"
12
+
13
+ override val engineVersion: String = THEOplayerGlobal.getVersion()
14
+ }
@@ -0,0 +1,27 @@
1
+ package com.twentyfouri.tvbridge.global.utils
2
+
3
+ import com.twentyfouri.player.base.PlayerFactoryBase
4
+
5
+ interface PlayerFactoryVersion {
6
+ val engineName: String
7
+ val engineVersion: String
8
+
9
+ private data class Fixed(
10
+ override val engineName: String,
11
+ override val engineVersion: String
12
+ ): PlayerFactoryVersion
13
+
14
+ companion object {
15
+ fun from(factory: PlayerFactoryBase): PlayerFactoryVersion {
16
+ (factory as? PlayerFactoryVersion)?.also { return it }
17
+
18
+ // fallback to just engine name
19
+ val engineName = factory.javaClass.simpleName
20
+ .replace("PlayerFactory", "")
21
+ .replace("Customized", "")
22
+ .lowercase()
23
+ val engineVersion = "0.0.0"
24
+ return Fixed(engineName, engineVersion)
25
+ }
26
+ }
27
+ }
@@ -1,7 +1,11 @@
1
1
  package com.twentyfouri.tvbridge.global.utils
2
2
 
3
+ import com.twentyfouri.player.base.Source
3
4
  import com.twentyfouri.player.base.SourceAuthorization
4
5
  import com.twentyfouri.player.base.SourceDrm
6
+ import com.twentyfouri.player.base.SourceDrmPlayready
7
+ import com.twentyfouri.player.base.SourceDrmWidevine
8
+ import com.twentyfouri.player.base.buildUpon
5
9
  import java.net.URI
6
10
 
7
11
  open class SourceDrmOverridden protected constructor(
@@ -33,6 +37,17 @@ open class SourceDrmOverridden protected constructor(
33
37
  var forceLicenseServer: Boolean = false
34
38
  var authorization: SourceAuthorization? = null
35
39
 
40
+ open fun applyFrom(source: SourceDrm) {
41
+ when (source) {
42
+ is SourceDrmOverridden -> applyFrom(source)
43
+ is SourceDrmWidevine -> applyFrom(source)
44
+ is SourceDrmPlayready -> applyFrom(source)
45
+ else -> {
46
+ packageName = source.packageName
47
+ }
48
+ }
49
+ }
50
+
36
51
  open fun applyFrom(source: SourceDrmOverridden) {
37
52
  packageName = source.packageName
38
53
  licenseServer = source.licenseServer
@@ -40,9 +55,36 @@ open class SourceDrmOverridden protected constructor(
40
55
  authorization = source.authorization
41
56
  }
42
57
 
58
+ open fun applyFrom(source: SourceDrmWidevine) {
59
+ packageName = source.packageName
60
+ licenseServer = source.licenseServer
61
+ forceLicenseServer = source.forceLicenseServer
62
+ authorization = source.authorization
63
+ }
64
+
65
+ open fun applyFrom(source: SourceDrmPlayready) {
66
+ packageName = source.packageName
67
+ licenseServer = source.licenseServer
68
+ forceLicenseServer = source.forceLicenseServer
69
+ authorization = source.authorization
70
+ }
71
+
43
72
  override fun build() =
44
73
  SourceDrmOverridden(this)
45
74
  }
75
+
76
+ companion object {
77
+ fun replaceSource(source: Source): Source {
78
+ if (source.drm.isEmpty()) return source
79
+ return source.buildUpon {
80
+ drm = drm.mapTo(mutableListOf()) { sourceDrm ->
81
+ SourceDrmOverridden {
82
+ applyFrom(sourceDrm)
83
+ }
84
+ }
85
+ }
86
+ }
87
+ }
46
88
  }
47
89
 
48
90
  inline fun SourceDrmOverridden(block: SourceDrmOverridden.Builder.() -> Unit) =
@@ -19,4 +19,7 @@ object MediaEventType {
19
19
  const val KEY_UP = "keyup"
20
20
  const val KEY_DOWN = "keydown"
21
21
  const val TRACKS_CHANGED = "tracksChanged"
22
+ const val AD_BREAK_START = "adbreakstart"
23
+ const val AD_BREAK_END = "adbreakend"
24
+ const val AD_BREAKS_RESCHEDULED = "adbreaksrescheduled"
22
25
  }