@24i/smartapps-bigscreen-rnv-build-engine 5.0.0-alpha.25 → 5.0.0

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 (86) hide show
  1. package/build-freshness.js +158 -0
  2. package/dist/.build-freshness.json +1010 -0
  3. package/dist/templates/platforms/firetv/project/README.md +196 -0
  4. package/dist/templates/platforms/firetv/project/amazoniap/build.gradle +41 -0
  5. package/dist/templates/platforms/firetv/project/amazoniap/consumer-rules.pro +0 -0
  6. package/dist/templates/platforms/firetv/project/amazoniap/proguard-rules.pro +21 -0
  7. package/dist/templates/platforms/firetv/project/amazoniap/src/main/kotlin/com/twentyfouri/bridgetv/amazoniap/AmazonIapService.kt +91 -0
  8. package/dist/templates/platforms/firetv/project/amazoniap/src/main/kotlin/com/twentyfouri/bridgetv/amazoniap/AmazonIapServiceFactory.kt +13 -0
  9. package/dist/templates/platforms/firetv/project/app/build.gradle +138 -0
  10. package/dist/templates/platforms/firetv/project/app/proguard-rules.pro +47 -0
  11. package/dist/templates/platforms/firetv/project/app/src/bigscreenAppstage/kotlin/com/twentyfouri/tvbridge/Flavor.kt +9 -0
  12. package/dist/templates/platforms/firetv/project/app/src/bigscreenAppstage/res/raw/configuration.json +8 -0
  13. package/dist/templates/platforms/firetv/project/app/src/main/AndroidManifest.xml +52 -0
  14. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/FlavorBase.kt +9 -0
  15. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/bridge/BridgeFromJavaScript.kt +421 -0
  16. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/bridge/BridgeToJavaScript.kt +121 -0
  17. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/configuration/BridgeConfig.kt +19 -0
  18. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/configuration/ConfigCallback.kt +6 -0
  19. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/configuration/ConfigProvider.kt +27 -0
  20. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/configuration/Drm.kt +10 -0
  21. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/configuration/UserAgent.kt +6 -0
  22. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/BaseApplication.kt +73 -0
  23. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/di/ActivityComponent.kt +13 -0
  24. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/di/ActivityModule.kt +14 -0
  25. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/di/ApplicationComponent.kt +23 -0
  26. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/di/ApplicationModule.kt +51 -0
  27. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/di/PerActivity.kt +26 -0
  28. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/LocalStorage.kt +30 -0
  29. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/LoggingDrmCallback.kt +38 -0
  30. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/OverriddenHttpMediaDrmCallback.kt +134 -0
  31. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/PlayerFactoryBitmovinCustomized.kt +19 -0
  32. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/PlayerFactoryConfigured.kt +37 -0
  33. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/PlayerFactoryExoPlayerCustomized.kt +106 -0
  34. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/PlayerFactoryExoPlayerNpaw.kt +581 -0
  35. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/PlayerFactoryVersion.kt +27 -0
  36. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/SimpleActivityLifecycleCallback.kt +32 -0
  37. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/global/utils/SourceDrmOverridden.kt +91 -0
  38. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/sound/TouchPlayer.kt +86 -0
  39. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/client/BridgeWebView.kt +82 -0
  40. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/client/BridgeWebViewClient.kt +114 -0
  41. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/model/AnalyticsPlaybackInfo.kt +10 -0
  42. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/model/ContentModel.kt +14 -0
  43. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/model/DrmModel.kt +20 -0
  44. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/model/MediaEventType.kt +31 -0
  45. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/parser/PlaybackInfoParser.kt +10 -0
  46. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/parser/SourceParser.kt +89 -0
  47. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/parser/TrackJsonModelParser.kt +58 -0
  48. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/view/Mainview.kt +18 -0
  49. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/view/PlayerCache.kt +15 -0
  50. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/view/WebViewActivity.kt +252 -0
  51. package/dist/templates/platforms/firetv/project/app/src/main/kotlin/com/twentyfouri/tvbridge/webview/viewmodel/WebViewModel.kt +748 -0
  52. package/dist/templates/platforms/firetv/project/app/src/main/res/drawable/button_background_focus.xml +10 -0
  53. package/dist/templates/platforms/firetv/project/app/src/main/res/drawable/button_background_normal.xml +7 -0
  54. package/dist/templates/platforms/firetv/project/app/src/main/res/drawable/button_background_pressed.xml +7 -0
  55. package/dist/templates/platforms/firetv/project/app/src/main/res/drawable/button_focus.xml +8 -0
  56. package/dist/templates/platforms/firetv/project/app/src/main/res/layout/activity_web_view.xml +28 -0
  57. package/dist/templates/platforms/firetv/project/app/src/main/res/raw/click.ogg +0 -0
  58. package/dist/templates/platforms/firetv/project/app/src/main/res/values/styles.xml +12 -0
  59. package/dist/templates/platforms/firetv/project/app/src/main/res/xml/network_security_config.xml +4 -0
  60. package/dist/templates/platforms/firetv/project/build.gradle +45 -0
  61. package/dist/templates/platforms/firetv/project/common/build.gradle +41 -0
  62. package/dist/templates/platforms/firetv/project/common/consumer-rules.pro +0 -0
  63. package/dist/templates/platforms/firetv/project/common/proguard-rules.pro +21 -0
  64. package/dist/templates/platforms/firetv/project/common/src/main/kotlin/com/twentyfouri/tvbridge/common/Util.kt +11 -0
  65. package/dist/templates/platforms/firetv/project/common/src/main/kotlin/com/twentyfouri/tvbridge/common/iap/IapCallback.kt +11 -0
  66. package/dist/templates/platforms/firetv/project/common/src/main/kotlin/com/twentyfouri/tvbridge/common/iap/IapException.kt +14 -0
  67. package/dist/templates/platforms/firetv/project/common/src/main/kotlin/com/twentyfouri/tvbridge/common/iap/IapProduct.kt +16 -0
  68. package/dist/templates/platforms/firetv/project/common/src/main/kotlin/com/twentyfouri/tvbridge/common/iap/IapPurchase.kt +9 -0
  69. package/dist/templates/platforms/firetv/project/common/src/main/kotlin/com/twentyfouri/tvbridge/common/iap/IapService.kt +14 -0
  70. package/dist/templates/platforms/firetv/project/common/src/main/kotlin/com/twentyfouri/tvbridge/common/iap/IapServiceFactory.kt +8 -0
  71. package/dist/templates/platforms/firetv/project/common/src/main/kotlin/com/twentyfouri/tvbridge/common/iap/NullIapService.kt +32 -0
  72. package/dist/templates/platforms/firetv/project/googleiap/build.gradle +41 -0
  73. package/dist/templates/platforms/firetv/project/googleiap/consumer-rules.pro +0 -0
  74. package/dist/templates/platforms/firetv/project/googleiap/proguard-rules.pro +21 -0
  75. package/dist/templates/platforms/firetv/project/googleiap/src/main/kotlin/com/twentyfouri/tvbridge/googleiap/GoogleIapService.kt +6 -0
  76. package/dist/templates/platforms/firetv/project/googleiap/src/main/kotlin/com/twentyfouri/tvbridge/googleiap/GoogleIapServiceFactory.kt +13 -0
  77. package/dist/templates/platforms/firetv/project/gradle/wrapper/gradle-wrapper.jar +0 -0
  78. package/dist/templates/platforms/firetv/project/gradle/wrapper/gradle-wrapper.properties +7 -0
  79. package/dist/templates/platforms/firetv/project/gradle.properties +4 -0
  80. package/dist/templates/platforms/firetv/project/gradlew +251 -0
  81. package/dist/templates/platforms/firetv/project/gradlew.bat +94 -0
  82. package/dist/templates/platforms/firetv/project/proguard-rules.pro +42 -0
  83. package/dist/templates/platforms/firetv/project/settings.gradle +4 -0
  84. package/index.js +2 -31
  85. package/package.json +4 -3
  86. package/project.json +57 -11
@@ -0,0 +1,13 @@
1
+ package com.twentyfouri.tvbridge.global.di
2
+
3
+ import android.app.Activity
4
+ import com.twentyfouri.tvbridge.webview.viewmodel.WebViewModel
5
+ import dagger.Component
6
+ import javax.inject.Provider
7
+
8
+ @PerActivity
9
+ @Component(dependencies = [ApplicationComponent::class], modules = [ActivityModule::class])
10
+ interface ActivityComponent : ApplicationComponent {
11
+ val activity: Activity
12
+ val viewModelFactory: Provider<WebViewModel>
13
+ }
@@ -0,0 +1,14 @@
1
+ package com.twentyfouri.tvbridge.global.di
2
+
3
+ import android.app.Activity
4
+ import dagger.Module
5
+ import dagger.Provides
6
+
7
+ @Module
8
+ class ActivityModule(
9
+ private val activity: Activity
10
+ ) {
11
+ @Provides
12
+ fun provideActivity() =
13
+ activity
14
+ }
@@ -0,0 +1,23 @@
1
+ package com.twentyfouri.tvbridge.global.di
2
+
3
+ import android.content.Context
4
+ import com.twentyfouri.player.base.PlayerFactoryBase
5
+ import com.twentyfouri.tvbridge.common.iap.IapService
6
+ import com.twentyfouri.tvbridge.configuration.BridgeConfig
7
+ import com.twentyfouri.tvbridge.global.BaseApplication
8
+ import com.twentyfouri.tvbridge.global.utils.LocalStorage
9
+ import com.twentyfouri.tvbridge.sound.TouchPlayer
10
+ import dagger.Component
11
+ import javax.inject.Singleton
12
+
13
+ @Singleton
14
+ @Component(modules = [ApplicationModule::class])
15
+ interface ApplicationComponent {
16
+ val application: BaseApplication
17
+ val localStorage: LocalStorage
18
+ val configuration: BridgeConfig
19
+ val playerFactory: PlayerFactoryBase
20
+ val applicationContext: Context
21
+ val touchPlayer: TouchPlayer
22
+ val iapService: IapService
23
+ }
@@ -0,0 +1,51 @@
1
+ package com.twentyfouri.tvbridge.global.di
2
+
3
+ import android.content.Context
4
+ import com.twentyfouri.player.base.PlayerFactoryBase
5
+ import com.twentyfouri.tvbridge.Flavor
6
+ import com.twentyfouri.tvbridge.common.iap.NullIapService
7
+ import com.twentyfouri.tvbridge.configuration.BridgeConfig
8
+ import com.twentyfouri.tvbridge.global.BaseApplication
9
+ import com.twentyfouri.tvbridge.global.utils.LocalStorage
10
+ import com.twentyfouri.tvbridge.global.utils.PlayerFactoryConfigured
11
+ import com.twentyfouri.tvbridge.sound.TouchPlayer
12
+ import dagger.Module
13
+ import dagger.Provides
14
+ import javax.inject.Singleton
15
+
16
+ @Module
17
+ class ApplicationModule(
18
+ private val baseApplication: BaseApplication,
19
+ private val configuration: BridgeConfig
20
+ ) {
21
+ @Provides
22
+ fun getApplication() = baseApplication
23
+
24
+ @Provides
25
+ fun getConfiguration() = configuration
26
+
27
+ @Provides
28
+ fun provideApplicationContext(): Context = baseApplication
29
+
30
+ @Singleton
31
+ @Provides
32
+ fun provideLocalStorage() = LocalStorage(baseApplication.applicationContext)
33
+
34
+ @Singleton
35
+ @Provides
36
+ fun provideTouchPlayer() = TouchPlayer(baseApplication)
37
+
38
+ @Singleton
39
+ @Provides
40
+ fun provideIapService() = Flavor
41
+ .iapServiceFactories
42
+ .firstOrNull { it.detectSupport(baseApplication) }
43
+ ?.build(baseApplication)
44
+ ?: NullIapService()
45
+
46
+ @Provides
47
+ @Singleton
48
+ fun providePlayerFactory(config: BridgeConfig): PlayerFactoryBase =
49
+ PlayerFactoryConfigured.buildFactory(config, baseApplication)
50
+
51
+ }
@@ -0,0 +1,26 @@
1
+ package com.twentyfouri.tvbridge.global.di
2
+
3
+ import javax.inject.Scope
4
+
5
+ /*
6
+ * Copyright (C) 2013 Square, Inc.
7
+ *
8
+ * Licensed under the Apache License, Version 2.0 (the "License");
9
+ * you may not use this file except in compliance with the License.
10
+ * You may obtain a copy of the License at
11
+ *
12
+ * http://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * Unless required by applicable law or agreed to in writing, software
15
+ * distributed under the License is distributed on an "AS IS" BASIS,
16
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ * See the License for the specific language governing permissions and
18
+ * limitations under the License.
19
+ */ /**
20
+ * A scoping annotation to permit objects whose lifetime should
21
+ * conform to the life of the activity to be memoized in the
22
+ * correct component.
23
+ */
24
+ @Scope
25
+ @kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
26
+ annotation class PerActivity
@@ -0,0 +1,30 @@
1
+ package com.twentyfouri.tvbridge.global.utils
2
+
3
+ import android.content.Context
4
+ import android.content.SharedPreferences
5
+
6
+ class LocalStorage(context: Context) {
7
+
8
+ private val preferences: SharedPreferences =
9
+ context.applicationContext.getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE)
10
+
11
+ fun saveCookieJson(key: String?, value: String?) {
12
+ val editor = preferences.edit()
13
+ editor.putString(key, value)
14
+ editor.apply()
15
+ }
16
+
17
+ fun removeFromLocalStorage(key: String?) {
18
+ val editor = preferences.edit()
19
+ editor.remove(key)
20
+ editor.apply()
21
+ }
22
+
23
+ fun getFromLocalStorage(key: String?): String? {
24
+ return preferences.getString(key, null)
25
+ }
26
+
27
+ companion object {
28
+ private const val SHARED_PREFERENCES = "com.twentyfouri.tvbridge"
29
+ }
30
+ }
@@ -0,0 +1,38 @@
1
+ package com.twentyfouri.tvbridge.global.utils
2
+
3
+ import android.util.Base64
4
+ import android.util.Log
5
+ import com.google.android.exoplayer2.drm.ExoMediaDrm
6
+ import com.google.android.exoplayer2.drm.MediaDrmCallback
7
+ import java.util.*
8
+
9
+ class LoggingDrmCallback(
10
+ private val base: MediaDrmCallback,
11
+ private val licenseUrl: String? = null
12
+ ) : MediaDrmCallback {
13
+ override fun executeProvisionRequest(
14
+ uuid: UUID,
15
+ request: ExoMediaDrm.ProvisionRequest
16
+ ): ByteArray {
17
+ return base.executeProvisionRequest(uuid, request)
18
+ }
19
+
20
+ override fun executeKeyRequest(uuid: UUID, request: ExoMediaDrm.KeyRequest): ByteArray {
21
+ if (com.twentyfouri.player.exoplayer.BuildConfig.DEBUG) {
22
+ Log.v(TAG, "DRM Embedded URL: ${request.licenseServerUrl}")
23
+ Log.v(TAG, "DRM Default URL: $licenseUrl")
24
+ Log.v(TAG, "DRM request:\n${request.data.toBase64()}")
25
+ }
26
+ val response = base.executeKeyRequest(uuid, request)
27
+ if (com.twentyfouri.player.exoplayer.BuildConfig.DEBUG) {
28
+ Log.v(TAG, "DRM response:\n" + response.toBase64())
29
+ }
30
+ return response
31
+ }
32
+
33
+ private fun ByteArray.toBase64(): String = Base64.encodeToString(this, Base64.DEFAULT)
34
+
35
+ companion object {
36
+ const val TAG = "DrmCallback"
37
+ }
38
+ }
@@ -0,0 +1,134 @@
1
+ package com.twentyfouri.tvbridge.global.utils
2
+
3
+ import android.net.Uri
4
+ import android.util.Base64
5
+ import android.util.Log
6
+ import com.google.android.exoplayer2.C
7
+ import com.google.android.exoplayer2.drm.ExoMediaDrm
8
+ import com.google.android.exoplayer2.drm.MediaDrmCallback
9
+ import com.google.android.exoplayer2.upstream.DataSourceInputStream
10
+ import com.google.android.exoplayer2.upstream.DataSpec
11
+ import com.google.android.exoplayer2.upstream.HttpDataSource
12
+ import com.google.android.exoplayer2.util.Util
13
+ import com.twentyfouri.tvbridge.BuildConfig
14
+ import org.json.JSONException
15
+ import org.json.JSONObject
16
+ import java.io.BufferedReader
17
+ import java.io.IOException
18
+ import java.io.InputStreamReader
19
+ import java.net.MalformedURLException
20
+ import java.net.URL
21
+ import java.net.URLEncoder
22
+ import java.util.HashMap
23
+ import java.util.UUID
24
+
25
+ class OverriddenHttpMediaDrmCallback(
26
+ private val defaultLicenseUrl: String?,
27
+ private val forceDefaultLicenseUrl: Boolean,
28
+ private val dataSourceFactory: HttpDataSource.Factory
29
+ ) : MediaDrmCallback {
30
+
31
+ @Throws(IOException::class)
32
+ override fun executeProvisionRequest(uuid: UUID, request: ExoMediaDrm.ProvisionRequest): ByteArray {
33
+ Log.d(TAG, "executeProvisionRequest")
34
+ val url = request.defaultUrl + "&signedRequest=" + String(request.data)
35
+ return executePost(dataSourceFactory, url, ByteArray(0), null)
36
+ }
37
+
38
+ @Throws(Exception::class)
39
+ override fun executeKeyRequest(uuid: UUID, request: ExoMediaDrm.KeyRequest): ByteArray {
40
+ Log.d(TAG, "executeKeyRequest")
41
+ var url: String? = request.licenseServerUrl
42
+ if (forceDefaultLicenseUrl || url.isNullOrEmpty()) {
43
+ url = defaultLicenseUrl
44
+ }
45
+ val requestProperties: MutableMap<String, String> = HashMap()
46
+ // Add standard request properties for supported schemes.
47
+ val contentType = "text/plain"
48
+ requestProperties["Content-Type"] = contentType
49
+ if (C.PLAYREADY_UUID == uuid) {
50
+ requestProperties["SOAPAction"] = "http://schemas.microsoft.com/DRM/2007/03/protocols/AcquireLicense"
51
+ }
52
+
53
+ //adding data to url
54
+ val challenge = request.data
55
+ val encoded = URLEncoder.encode(Base64.encodeToString(challenge, Base64.NO_WRAP), "UTF-8")
56
+ url = appendQuery(url, "_widevineChallenge=$encoded")
57
+ if (BuildConfig.DEBUG) {
58
+ Log.d(TAG, "Executing post on url $url with content type $contentType")
59
+ }
60
+ return executeGet(url)
61
+ }
62
+
63
+ companion object {
64
+ private const val TAG = "DrmCallback"
65
+
66
+ private fun executeGet(urlString: String): ByteArray {
67
+ try {
68
+ val licenserRequest = URL(urlString)
69
+ val yc = licenserRequest.openConnection()
70
+ val input = BufferedReader(InputStreamReader(yc.getInputStream()))
71
+ val builder = StringBuilder()
72
+ var inputLine: String?
73
+ while (input.readLine().also { inputLine = it } != null) {
74
+ builder.append(inputLine)
75
+ }
76
+ input.close()
77
+ val jsonObject = JSONObject(builder.toString())
78
+ val container = jsonObject.getJSONObject("getWidevineLicenseResponse")
79
+ val license = container.getString("license")
80
+ if (BuildConfig.DEBUG) {
81
+ Log.d(TAG, "Finished post: $license")
82
+ }
83
+ return Base64.decode(license, Base64.NO_WRAP)
84
+ } catch (e: MalformedURLException) {
85
+ e.printStackTrace()
86
+ } catch (e: IOException) {
87
+ e.printStackTrace()
88
+ } catch (e: JSONException) {
89
+ e.printStackTrace()
90
+ }
91
+ return byteArrayOf()
92
+ }
93
+
94
+ @Throws(IOException::class)
95
+ private fun executePost(
96
+ dataSourceFactory: HttpDataSource.Factory,
97
+ url: String,
98
+ data: ByteArray,
99
+ requestProperties: Map<String, String>?
100
+ ): ByteArray {
101
+ Log.d(TAG, "executePost")
102
+ val dataSource = dataSourceFactory.createDataSource()
103
+ if (requestProperties != null) {
104
+ for ((key, value) in requestProperties) {
105
+ dataSource.setRequestProperty(key, value)
106
+ }
107
+ }
108
+ val dataSpec = DataSpec.Builder()
109
+ .setUri(Uri.parse(url))
110
+ .setFlags(DataSpec.FLAG_ALLOW_GZIP)
111
+ .setHttpMethod(DataSpec.HTTP_METHOD_POST)
112
+ .setHttpBody(data)
113
+ .setHttpRequestHeaders(requestProperties ?: emptyMap())
114
+ .build()
115
+ val inputStream = DataSourceInputStream(dataSource, dataSpec)
116
+ return try {
117
+ Util.toByteArray(inputStream)
118
+ } finally {
119
+ Util.closeQuietly(inputStream)
120
+ }
121
+ }
122
+
123
+ fun appendQuery(url: String?, appendQuery: String): String {
124
+ val oldUri = Uri.parse(url)
125
+ var newQuery = oldUri.query
126
+ if (newQuery == null) {
127
+ newQuery = appendQuery
128
+ } else {
129
+ newQuery += "&$appendQuery"
130
+ }
131
+ return oldUri.scheme + "://" + oldUri.authority + oldUri.path + "?" + newQuery
132
+ }
133
+ }
134
+ }
@@ -0,0 +1,19 @@
1
+ package com.twentyfouri.tvbridge.global.utils
2
+
3
+ import android.app.Application
4
+ import com.twentyfouri.player.bitmovin.NpawConfig
5
+ import com.twentyfouri.player.bitmovin.PlayerBitmovin
6
+ import com.twentyfouri.player.bitmovin.PlayerFactoryBitmovin
7
+ import com.twentyfouri.tvbridge.configuration.BridgeConfig
8
+
9
+ class PlayerFactoryBitmovinCustomized(config: BridgeConfig, application: Application) :
10
+ PlayerFactoryBitmovin(
11
+ config.bitmovinLicense,
12
+ if (config.npawAccount.isNotEmpty()) {
13
+ NpawConfig(config.npawAccount, application)
14
+ } else {
15
+ null
16
+ },
17
+ config.bitmovinAnalytics.ifEmpty { PlayerBitmovin.ANALYTICS_LICENSE_DEFERRED }
18
+ ),
19
+ PlayerFactoryVersion
@@ -0,0 +1,37 @@
1
+ package com.twentyfouri.tvbridge.global.utils
2
+
3
+ import android.app.Application
4
+ import com.twentyfouri.player.base.PlayerFactoryBase
5
+ import com.twentyfouri.tvbridge.configuration.BridgeConfig
6
+
7
+ object PlayerFactoryConfigured {
8
+ fun buildFactory(bridgeConfig: BridgeConfig, application: Application): PlayerFactoryBase {
9
+ var factory: PlayerFactoryBase? = null
10
+ if (bridgeConfig.bitmovinLicense.isNotEmpty()) {
11
+ factory = factory ?: buildBitmovinFactory(bridgeConfig, application)
12
+ }
13
+ if (bridgeConfig.npawAccount.isNotEmpty()) {
14
+ factory = factory ?: buildNpawFactory(bridgeConfig)
15
+ }
16
+ factory = factory ?: buildExoFactory(bridgeConfig)
17
+ return factory ?: throw Exception("Cannot create player factory")
18
+ }
19
+
20
+ private fun buildExoFactory(bridgeConfig: BridgeConfig) = try {
21
+ PlayerFactoryExoPlayerCustomized(bridgeConfig)
22
+ } catch (e: NoClassDefFoundError) {
23
+ null
24
+ }
25
+
26
+ private fun buildNpawFactory(bridgeConfig: BridgeConfig) = try {
27
+ PlayerFactoryExoPlayerNpaw(bridgeConfig)
28
+ } catch (e: NoClassDefFoundError) {
29
+ null
30
+ }
31
+
32
+ private fun buildBitmovinFactory(bridgeConfig: BridgeConfig, application: Application) = try {
33
+ PlayerFactoryBitmovinCustomized(bridgeConfig, application)
34
+ } catch (e: NoClassDefFoundError) {
35
+ null
36
+ }
37
+ }
@@ -0,0 +1,106 @@
1
+ package com.twentyfouri.tvbridge.global.utils
2
+
3
+ import android.content.Context
4
+ import com.google.android.exoplayer2.C
5
+ import com.google.android.exoplayer2.ExoPlayerLibraryInfo
6
+ import com.google.android.exoplayer2.drm.DefaultDrmSessionManager
7
+ import com.google.android.exoplayer2.drm.DrmSessionManager
8
+ import com.google.android.exoplayer2.drm.FrameworkMediaDrm
9
+ import com.google.android.exoplayer2.drm.MediaDrmCallback
10
+ import com.google.android.exoplayer2.ext.ima.ImaAdsLoader
11
+ import com.google.android.exoplayer2.upstream.HttpDataSource
12
+ import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy
13
+ import com.twentyfouri.player.base.DrmPlayready
14
+ import com.twentyfouri.player.base.DrmWidevine
15
+ import com.twentyfouri.player.base.Source
16
+ import com.twentyfouri.player.base.SourceDrm
17
+ import com.twentyfouri.player.base.TimeProvider
18
+ import com.twentyfouri.player.exoplayer.*
19
+ import com.twentyfouri.tvbridge.configuration.BridgeConfig
20
+
21
+ class PlayerFactoryExoPlayerCustomized(
22
+ private val config: BridgeConfig
23
+ ) : PlayerFactoryExoPlayer(), PlayerFactoryVersion {
24
+
25
+ override val engineName: String = "Exoplayer"
26
+
27
+ override val engineVersion: String = ExoPlayerLibraryInfo.VERSION
28
+
29
+ override fun createSharedComponents(context: Context): SharedComponents =
30
+ CustomizedSharedComponents(context)
31
+
32
+ private inner class CustomizedSharedComponents(context: Context) : DefaultSharedComponents(context) {
33
+
34
+ override val drmProvider: DrmSessionManagerProvider by lazy {
35
+ CustomizedDrmSessionManagerProvider(loadErrorHandlingPolicy)
36
+ }
37
+
38
+ override val applicationName: String
39
+ get() = config.playerAppName ?: super.applicationName
40
+
41
+ override fun buildIsolatedComponents(): PlayerComponents {
42
+ return CustomizedPlayerComponents(this)
43
+ }
44
+
45
+ override val mainSourceProvider: MediaSourceFactoryProvider by lazy {
46
+ DefaultMediaSourceFactoryProvider().also {
47
+ it.useLiveMediaTailorWorkaround = true
48
+ }
49
+ }
50
+
51
+ override val focusSkipButton: Boolean
52
+ get() = false
53
+ }
54
+
55
+ private inner class CustomizedPlayerComponents(shared: SharedComponents) : DefaultPlayerComponents(shared) {
56
+ override val handleAudioFocus: Boolean
57
+ get() = false
58
+ }
59
+
60
+ private class CustomizedDrmSessionManagerProvider(
61
+ loadErrorHandlingPolicy: LoadErrorHandlingPolicy
62
+ ) : DefaultDrmSessionManagerProvider(loadErrorHandlingPolicy) {
63
+ override fun buildDrmSessionManager(
64
+ dataSourceFactory: AuthorizedDataSourceProvider,
65
+ source: Source,
66
+ sourceDrm: SourceDrm
67
+ ): DrmSessionManager? {
68
+ if (sourceDrm is SourceDrmOverridden) {
69
+ return buildDrmOverridden(dataSourceFactory, sourceDrm)
70
+ } else {
71
+ return super.buildDrmSessionManager(dataSourceFactory, source, sourceDrm)
72
+ }
73
+ }
74
+
75
+ private fun buildDrmOverridden(dataSourceFactory: AuthorizedDataSourceProvider, sourceDrm: SourceDrmOverridden): DrmSessionManager? {
76
+ val drmUuid = when (sourceDrm.packageName) {
77
+ DrmWidevine.packageName -> C.WIDEVINE_UUID
78
+ DrmPlayready.packageName -> C.PLAYREADY_UUID
79
+ else -> C.UUID_NIL
80
+ }
81
+ val licenseUrl = sourceDrm.licenseServer?.toString() ?: ""
82
+ val forceLicenseUrl = sourceDrm.forceLicenseServer
83
+ val httpDataSourceFactory = dataSourceFactory.buildHttpDataSourceFactory(sourceDrm.authorization)
84
+
85
+ val drmCallback = LoggingDrmCallback(
86
+ OverriddenHttpMediaDrmCallback(
87
+ licenseUrl,
88
+ forceLicenseUrl,
89
+ httpDataSourceFactory
90
+ ),
91
+ licenseUrl
92
+ )
93
+
94
+ return DefaultDrmSessionManager.Builder()
95
+ .setUuidAndExoMediaDrmProvider(drmUuid, FrameworkMediaDrm.DEFAULT_PROVIDER)
96
+ .setMultiSession(false)
97
+ .setLoadErrorHandlingPolicy(loadErrorHandlingPolicy)
98
+ .build(drmCallback)
99
+ }
100
+
101
+ override fun buildDrmCallback(licenseUrl: String, forceLicenseUrl: Boolean, httpDataSourceFactory: HttpDataSource.Factory): MediaDrmCallback {
102
+ return LoggingDrmCallback(super.buildDrmCallback(licenseUrl, forceLicenseUrl, httpDataSourceFactory), licenseUrl)
103
+ }
104
+ }
105
+ }
106
+