@24i/smartapps-bigscreen-rnv-build-engine 0.17.2-alpha.2168 → 0.17.2

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 (94) hide show
  1. package/dist/src/resolvers/index.js +1 -3
  2. package/dist/src/resolvers/resolveBuildFileName.js +27 -3
  3. package/dist/src/sdks/index.js +1 -5
  4. package/dist/src/sdks/sdk-utils/sdk-installer/services/unzip.js +2 -3
  5. package/dist/src/tasks/task.rnv.build.js +1 -3
  6. package/dist/src/tasks/task.rnv.configure.js +1 -3
  7. package/dist/src/tasks/task.rnv.platform.configure.js +1 -4
  8. package/package.json +2 -3
  9. package/dist/src/__tests__/resolvers/resolveBuildFileBaseName.spec.js +0 -80
  10. package/dist/src/resolvers/resolveBuildFileBaseName.js +0 -34
  11. package/dist/src/sdks/sdk-androidtv/index.js +0 -17
  12. package/dist/src/sdks/sdk-androidtv/sdkAndroidtv.js +0 -260
  13. package/dist/templates/platforms/androidtv/project/README.md +0 -198
  14. package/dist/templates/platforms/androidtv/project/amazoniap/build.gradle +0 -37
  15. package/dist/templates/platforms/androidtv/project/amazoniap/consumer-rules.pro +0 -0
  16. package/dist/templates/platforms/androidtv/project/amazoniap/libs/in-app-purchasing-2.0.76.jar +0 -0
  17. package/dist/templates/platforms/androidtv/project/amazoniap/proguard-rules.pro +0 -21
  18. package/dist/templates/platforms/androidtv/project/amazoniap/src/main/AndroidManifest.xml +0 -4
  19. package/dist/templates/platforms/androidtv/project/amazoniap/src/main/java/com/twentyfouri/bridgetv/amazoniap/AmazonIapSevice.kt +0 -106
  20. package/dist/templates/platforms/androidtv/project/app/build.gradle +0 -112
  21. package/dist/templates/platforms/androidtv/project/app/proguard-rules.pro +0 -32
  22. package/dist/templates/platforms/androidtv/project/app/src/bigscreenAppstage/java/com/twentyfouri/tvbridge/Flavor.kt +0 -5
  23. package/dist/templates/platforms/androidtv/project/app/src/bigscreenAppstage/res/raw/configuration.json +0 -9
  24. package/dist/templates/platforms/androidtv/project/app/src/main/AndroidManifest.xml +0 -53
  25. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/FlavorBase.kt +0 -12
  26. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/bridge/BridgeFromJavaScript.kt +0 -385
  27. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/bridge/BridgeToJavaScript.kt +0 -83
  28. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/configuration/BridgeConfig.kt +0 -16
  29. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/configuration/ConfigCallback.kt +0 -6
  30. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/configuration/ConfigProvider.kt +0 -27
  31. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/configuration/Drm.kt +0 -10
  32. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/configuration/UserAgent.kt +0 -6
  33. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/BaseApplication.kt +0 -73
  34. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/di/ActivityComponent.kt +0 -13
  35. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/di/ActivityModule.kt +0 -21
  36. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/di/ApplicationComponent.kt +0 -24
  37. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/di/ApplicationModule.kt +0 -43
  38. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/di/PerActivity.kt +0 -26
  39. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/utils/LocalStorage.kt +0 -30
  40. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/utils/LoggingDrmCallback.kt +0 -38
  41. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/utils/OverriddenHttpMediaDrmCallback.kt +0 -134
  42. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/utils/PlayerFactoryExoPlayerCustomized.kt +0 -84
  43. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/utils/SimpleActivityLifecycleCallback.kt +0 -32
  44. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/global/utils/SourceDrmOverridden.kt +0 -49
  45. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/jump/JumpAnalytics.kt +0 -211
  46. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/sound/TouchPlayer.kt +0 -86
  47. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/client/BridgeWebView.kt +0 -82
  48. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/client/BridgeWebViewClient.kt +0 -114
  49. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/model/AnalyticsPlaybackInfo.kt +0 -10
  50. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/model/ContentModel.kt +0 -14
  51. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/model/DrmModel.kt +0 -20
  52. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/model/MediaEventType.kt +0 -20
  53. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/parser/ContentModelParser.kt +0 -16
  54. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/parser/DeviceInfoParser.kt +0 -22
  55. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/parser/PlaybackInfoParser.kt +0 -10
  56. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/parser/TrackJsonModelParser.kt +0 -58
  57. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/view/Mainview.kt +0 -20
  58. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/view/PlayerCache.kt +0 -15
  59. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/view/WebViewActivity.kt +0 -301
  60. package/dist/templates/platforms/androidtv/project/app/src/main/java/com/twentyfouri/tvbridge/webview/viewmodel/WebViewModel.kt +0 -571
  61. package/dist/templates/platforms/androidtv/project/app/src/main/res/drawable/banner.png +0 -0
  62. package/dist/templates/platforms/androidtv/project/app/src/main/res/drawable/button_background_focus.xml +0 -10
  63. package/dist/templates/platforms/androidtv/project/app/src/main/res/drawable/button_background_normal.xml +0 -7
  64. package/dist/templates/platforms/androidtv/project/app/src/main/res/drawable/button_background_pressed.xml +0 -7
  65. package/dist/templates/platforms/androidtv/project/app/src/main/res/drawable/button_focus.xml +0 -8
  66. package/dist/templates/platforms/androidtv/project/app/src/main/res/layout/activity_web_view.xml +0 -76
  67. package/dist/templates/platforms/androidtv/project/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  68. package/dist/templates/platforms/androidtv/project/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  69. package/dist/templates/platforms/androidtv/project/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  70. package/dist/templates/platforms/androidtv/project/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  71. package/dist/templates/platforms/androidtv/project/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  72. package/dist/templates/platforms/androidtv/project/app/src/main/res/raw/click.ogg +0 -0
  73. package/dist/templates/platforms/androidtv/project/app/src/main/res/raw/fiddle_root_michal_konecny.cer +0 -0
  74. package/dist/templates/platforms/androidtv/project/app/src/main/res/raw/proxy_milanwilczak.pem +0 -26
  75. package/dist/templates/platforms/androidtv/project/app/src/main/res/values/styles.xml +0 -12
  76. package/dist/templates/platforms/androidtv/project/app/src/main/res/xml/network_security_config.xml +0 -12
  77. package/dist/templates/platforms/androidtv/project/build.gradle +0 -48
  78. package/dist/templates/platforms/androidtv/project/common/build.gradle +0 -36
  79. package/dist/templates/platforms/androidtv/project/common/consumer-rules.pro +0 -0
  80. package/dist/templates/platforms/androidtv/project/common/proguard-rules.pro +0 -21
  81. package/dist/templates/platforms/androidtv/project/common/src/main/AndroidManifest.xml +0 -4
  82. package/dist/templates/platforms/androidtv/project/common/src/main/java/com/twentyfouri/tvbridge/common/IapService.kt +0 -114
  83. package/dist/templates/platforms/androidtv/project/googleiap/build.gradle +0 -38
  84. package/dist/templates/platforms/androidtv/project/googleiap/consumer-rules.pro +0 -0
  85. package/dist/templates/platforms/androidtv/project/googleiap/proguard-rules.pro +0 -21
  86. package/dist/templates/platforms/androidtv/project/googleiap/src/main/AndroidManifest.xml +0 -6
  87. package/dist/templates/platforms/androidtv/project/googleiap/src/main/java/com/twentyfouri/tvbridge/googleiap/GoogleIapService.kt +0 -29
  88. package/dist/templates/platforms/androidtv/project/gradle/wrapper/gradle-wrapper.jar +0 -0
  89. package/dist/templates/platforms/androidtv/project/gradle/wrapper/gradle-wrapper.properties +0 -6
  90. package/dist/templates/platforms/androidtv/project/gradle.properties +0 -4
  91. package/dist/templates/platforms/androidtv/project/gradlew +0 -185
  92. package/dist/templates/platforms/androidtv/project/gradlew.bat +0 -104
  93. package/dist/templates/platforms/androidtv/project/proguard-rules.pro +0 -42
  94. package/dist/templates/platforms/androidtv/project/settings.gradle +0 -4
@@ -1,571 +0,0 @@
1
- package com.twentyfouri.tvbridge.webview.viewmodel
2
-
3
- import android.app.Activity
4
- import android.content.Context
5
- import android.content.Intent
6
- import android.graphics.Bitmap
7
- import android.graphics.Canvas
8
- import android.net.Uri
9
- import android.os.Build
10
- import android.util.Log
11
- import android.view.KeyEvent
12
- import android.view.View
13
- import android.webkit.CookieManager
14
- import android.webkit.WebChromeClient
15
- import android.webkit.WebView
16
- import androidx.databinding.BaseObservable
17
- import androidx.databinding.Bindable
18
- import com.google.android.exoplayer2.C
19
- import com.google.android.exoplayer2.SeekParameters
20
- import com.google.gson.JsonArray
21
- import com.google.gson.JsonObject
22
- import com.twentyfouri.player.base.*
23
- import com.twentyfouri.player.exoplayer.PlayerExoPlayer
24
- import com.twentyfouri.tvbridge.BR
25
- import com.twentyfouri.tvbridge.BuildConfig
26
- import com.twentyfouri.tvbridge.Flavor
27
- import com.twentyfouri.tvbridge.bridge.BridgeFromJavaScript
28
- import com.twentyfouri.tvbridge.bridge.BridgeToJavaScript
29
- import com.twentyfouri.tvbridge.common.*
30
- import com.twentyfouri.tvbridge.configuration.BridgeConfig
31
- import com.twentyfouri.tvbridge.global.utils.LocalStorage
32
- import com.twentyfouri.tvbridge.global.utils.SourceDrmOverridden
33
- import com.twentyfouri.tvbridge.jump.JumpAnalytics
34
- import com.twentyfouri.tvbridge.webview.client.BridgeWebView
35
- import com.twentyfouri.tvbridge.webview.client.BridgeWebViewClient
36
- import com.twentyfouri.tvbridge.webview.client.BridgeWebViewClient.BridgeWebViewClientCallback
37
- import com.twentyfouri.tvbridge.webview.model.AnalyticsPlaybackInfo
38
- import com.twentyfouri.tvbridge.webview.model.ContentModel
39
- import com.twentyfouri.tvbridge.webview.model.DrmModel
40
- import com.twentyfouri.tvbridge.webview.model.MediaEventType
41
- import com.twentyfouri.tvbridge.webview.view.Mainview
42
- import com.twentyfouri.tvbridge.webview.view.PlayerCache
43
- import java.net.URI
44
- import javax.inject.Inject
45
-
46
- /**
47
- * Created by destivar on 15/02/16.
48
- */
49
- class WebViewModel @Inject constructor(
50
- private val context: Context,
51
- private val localStorage: LocalStorage,
52
- private val config: BridgeConfig,
53
- private val iapService: IapService,
54
- val playerFactory: PlayerFactoryBase
55
- ) : BaseObservable(), EventListener {
56
- var player: PlayerBase? = null
57
- private var view: Mainview? = null
58
- private val jsBridge = BridgeToJavaScript(config) { s: String? ->
59
- view?.loadUrl(s)
60
- }
61
- private val iapCallback = InnerIapCallback()
62
- private val playerCache = PlayerCache()
63
- private val jumpAnalytics = JumpAnalytics()
64
-
65
- private var contentModel: ContentModel? = null
66
-
67
- val audioTrack: AudioTrack?
68
- get() = player?.selectedAudioTrack
69
- val subtitleTrack: TextTrack?
70
- get() = player?.selectedTextTrack
71
-
72
- var appUrl: String? = null
73
-
74
- var urlSetterVisible: Boolean = false
75
- set(value) {
76
- if (field == value) return
77
- field = value
78
- notifyPropertyChanged(BR.urlSetterVisibility)
79
- }
80
-
81
- @get:Bindable
82
- val urlSetterVisibility: Int
83
- get() = if (urlSetterVisible) View.VISIBLE else View.GONE
84
-
85
- fun attachView(view: Mainview?) {
86
- this.view = view
87
- if (view != null) {
88
- iapService.initialize()
89
- checkNewPurchases()
90
- }
91
- }
92
-
93
- fun configureWebView(webView: BridgeWebView) {
94
-
95
- // Enable remote debugging on devices at API level 19 (KitKat) or higher.
96
- if (BuildConfig.DEBUG) {
97
- WebView.setWebContentsDebuggingEnabled(true)
98
- }
99
-
100
- // Add the JavaScript bridge.
101
- webView.addJavascriptInterface(BridgeFromJavaScript(this), JAVA_SCRIPT_BRIDGE)
102
-
103
- // WebView callback methods.
104
- webView.webViewClient = BridgeWebViewClient(object : BridgeWebViewClientCallback {
105
- override fun onUnhandledKeyEvent(view: WebView, event: KeyEvent) {
106
- if (event.action == KeyEvent.ACTION_DOWN) {
107
- sendKeyCode(event.keyCode, MediaEventType.KEY_DOWN)
108
- } else if (event.action == KeyEvent.ACTION_UP) {
109
- sendKeyCode(event.keyCode, MediaEventType.KEY_UP)
110
- }
111
- }
112
- })
113
-
114
- webView.webChromeClient = object : WebChromeClient() {
115
- override fun getDefaultVideoPoster(): Bitmap? {
116
- val bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565)
117
- val canvas = Canvas(bitmap)
118
- canvas.drawARGB(255, 0, 0, 0)
119
- return bitmap
120
- }
121
-
122
- override fun onShowCustomView(view: View, callback: CustomViewCallback) {
123
- val intent = Intent(Intent.ACTION_SEND)
124
- intent.type = "video/*"
125
- context.startActivity(intent)
126
- }
127
-
128
- override fun onHideCustomView() {}
129
- }
130
-
131
- webView.previewKeyEvent = this::dispatchKeyEvent
132
-
133
- CookieManager.getInstance().setAcceptCookie(true)
134
- CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true)
135
- }
136
-
137
- fun onClickGo() {
138
- view?.loadUrl(appUrl)
139
- urlSetterVisible = false
140
- if (BuildConfig.DEBUG) {
141
- view?.hideKeyboard()
142
- }
143
- }
144
-
145
- fun setVideo(contentModel: ContentModel) {
146
- logContentModel(contentModel)
147
- playDirectly(contentModel)
148
- }
149
-
150
- private fun logContentModel(contentModel: ContentModel) {
151
- Log.i("BridgeVideo", "Url: " + contentModel.streamUrl)
152
- val drmModel = contentModel.drmModel
153
- if (drmModel != null) {
154
- Log.i("BridgeVideo", "DRM: " + drmModel.drmSchemeUuid)
155
- Log.i("BridgeVideo", "LicenseUrl: " + drmModel.drmLicenseUrl)
156
- }
157
- }
158
-
159
- private fun playInExoPlayerDemoApp(contentModel: ContentModel) {
160
- val intent = Intent("com.google.android.exoplayer.demo.action.VIEW", Uri.parse(contentModel.streamUrl))
161
- val drmModel = contentModel.drmModel
162
- if (drmModel != null) {
163
- intent.putExtra("drm_scheme", drmModel.drmSchemeUuid)
164
- intent.putExtra("drm_license_url", drmModel.drmLicenseUrl)
165
- }
166
- try {
167
- context.startActivity(intent)
168
- } catch (e: Exception) {
169
- Log.w("WebViewModel", "Failed to start ExoPlayer demo app", e)
170
- }
171
- }
172
-
173
- private fun playDirectly(contentModel: ContentModel) {
174
- this.contentModel = contentModel
175
- (player as? PlayerExoPlayer)?.exoPlayer?.also { exoPlayer ->
176
- jumpAnalytics.setVideoPlayer(exoPlayer)
177
- exoPlayer.setSeekParameters(SeekParameters.CLOSEST_SYNC)
178
- }
179
- player?.also { player ->
180
- player.source = Source {
181
- url = contentModel.streamUrl?.let { URI(it) }
182
- mimeType = detectMimeType(contentModel)
183
- contentModel.drmModel?.let { buildDrm(it) }?.also { drm.add(it) }
184
- }
185
-
186
- if (isLowEndDevice) {
187
- player.trackRestrictions = player.trackRestrictions.buildUpon {
188
- maxBitrate = LOW_END_DEVICE_MAX_BITRATE
189
- }
190
- } else if (config.startWithHighVideoQuality) {
191
- player.trackRestrictions = player.trackRestrictions.buildUpon {
192
- abrStrategy = AbrStrategy.QUALITY
193
- }
194
- }
195
-
196
- player.addEventListener(Event.ALL, this)
197
-
198
- player.autoPlay = true
199
- player.load()
200
- player.play()
201
- }
202
- }
203
-
204
- private fun detectMimeType(contentModel: ContentModel) =
205
- when (contentModel.streamType) {
206
- null, "" -> null
207
- ".mpd", "mpd", "dash" -> ManifestDash.mimeType
208
- ".ism", "ism", "ss" -> ManifestSmoothStreaming.mimeType
209
- ".m3u8", "m3u8", "hls" -> ManifestHls.mimeType
210
- else -> null
211
- }
212
-
213
- private fun buildDrm(drmModel: DrmModel): SourceDrm? {
214
- val drmScheme = drmModel.drmSchemeUuid
215
- val useOverride = drmModel.overrideDrmCallback ?: config.drm.shouldOverrideDrmCallback()
216
- val useWidevine = drmScheme == "widevine" || drmScheme == C.WIDEVINE_UUID.toString()
217
- val usePlayReady = drmScheme == "playready" || drmScheme == C.PLAYREADY_UUID.toString()
218
- return when {
219
- drmScheme == null -> null
220
- useOverride -> SourceDrmOverridden {
221
- packageName = when {
222
- useWidevine -> DrmWidevine.packageName
223
- usePlayReady -> DrmPlayready.packageName
224
- else -> ""
225
- }
226
- licenseServer = drmModel.drmLicenseUrl?.let { URI(it) }
227
- forceLicenseServer = true
228
- }
229
- useWidevine -> SourceDrmWidevine {
230
- licenseServer = drmModel.drmLicenseUrl?.let { URI(it) }
231
- forceLicenseServer = true
232
- }
233
- usePlayReady -> SourceDrmWidevine {
234
- licenseServer = drmModel.drmLicenseUrl?.let { URI(it) }
235
- forceLicenseServer = true
236
- }
237
- else -> SourceDrmUnrecognized(drmScheme)
238
- }
239
- }
240
-
241
- private val isLowEndDevice: Boolean
242
- get() = when (Build.MODEL) {
243
- "AFTB" -> true
244
- "AFTM" -> true
245
- else -> false
246
- }
247
-
248
- fun startPlayer() {
249
- player?.play()
250
- }
251
-
252
- fun resumePlayer() {
253
- val savedContentModel = playerCache.savedContentModel
254
- if (playerCache.loadFromCache && savedContentModel != null && playerCache.savedPlayerState !== PlayerCache.PlayerState.PAUSED) {
255
- setVideo(savedContentModel)
256
- var position = playerCache.savedPlayerPosition
257
- val player = this.player ?: return
258
- if (player.live) {
259
- position = 0.0
260
- }
261
- player.seek(position)
262
- view?.requestAudioFocus()
263
- if (playerCache.savedPlayerState === PlayerCache.PlayerState.PLAYING) {
264
- player.play()
265
- }
266
- } else {
267
- if (player?.live == true) {
268
- player?.seek(0.0)
269
- }
270
- player?.play()
271
- }
272
- }
273
-
274
- fun pausePlayer() {
275
- player?.pause()
276
- }
277
-
278
- fun stopPlayer() {
279
- view?.setBlackCurtainVisibility(View.VISIBLE)
280
- contentModel = null
281
-
282
- player?.also { player ->
283
- player.removeEventListener(Event.ALL, this)
284
- player.unload()
285
- jumpAnalytics.setVideoPlayer(null)
286
- }
287
- }
288
-
289
- fun releasePlayer() {
290
- val player = this.player ?: return
291
- if (contentModel != null) {
292
- playerCache.loadFromCache = true
293
- playerCache.savedContentModel = contentModel
294
- playerCache.savedPlayerDuration = player.duration
295
- playerCache.savedPlayerPosition = player.currentTime
296
- playerCache.savedPlayerState = if (player.playing) PlayerCache.PlayerState.PLAYING else PlayerCache.PlayerState.PAUSED
297
- }
298
- player.unload()
299
- jumpAnalytics.setVideoPlayer(null)
300
- }
301
-
302
- val currentPosition: Double
303
- get() = player?.currentTime ?: playerCache.savedPlayerPosition
304
- val duration: Double
305
- get() = player?.duration ?: playerCache.savedPlayerDuration
306
-
307
- fun seekToPosition(position: Double) {
308
- player?.seek(position)
309
- }
310
-
311
- val isPlayerPlaying: Boolean
312
- get() = player?.playing == true
313
- val isInPlayer: Boolean
314
- get() = player != null && contentModel != null
315
-
316
- fun loadUrl(url: String?) {
317
- view?.loadUrl(url)
318
- }
319
-
320
- fun setSubtitlesVisibility(visibility: Boolean) {
321
- val player = this.player ?: return
322
- if (visibility) {
323
- player.trackRestrictions = player.trackRestrictions.buildUpon {
324
- enableCaptions = true
325
- }
326
- if (player.textTrack?.kind == TrackKind.EMPTY) {
327
- player.textTrack = null
328
- }
329
- } else {
330
- player.trackRestrictions = player.trackRestrictions.buildUpon {
331
- enableCaptions = false
332
- }
333
- player.textTrack = player.textTracks.firstOrNull { it.kind == TrackKind.EMPTY }
334
- ?: DISABLED_TEXT_TRACK
335
- }
336
- }
337
-
338
- fun enableFullScreen() {
339
- view?.goFullscreen()
340
- }
341
-
342
- fun disableFullScreen(width: Int, height: Int, left: Int, top: Int) {
343
- view?.exitFullscreen(width, height, left, top)
344
- }
345
-
346
- override fun onEvent(event: Event) {
347
- val player = this.player ?: return
348
- when (event) {
349
- is ErrorEvent -> {
350
- Log.e("AndroidPlayer", "Player error", event.error)
351
- jsBridge.bridgeAndroidToJavaScript_MediaEvent(MediaEventType.ERROR)
352
- stopPlayer()
353
- }
354
- is EndedEvent -> {
355
- jsBridge.bridgeAndroidToJavaScript_MediaEvent(MediaEventType.ENDED)
356
- }
357
- is WaitingEvent -> {
358
- jsBridge.bridgeAndroidToJavaScript_MediaEvent(MediaEventType.WAITING)
359
- }
360
- is PlayingEvent -> {
361
- view?.setBlackCurtainVisibility(View.GONE)
362
- jsBridge.bridgeAndroidToJavaScript_MediaEvent(MediaEventType.PLAYING)
363
- }
364
- is SeekedEvent -> {
365
- jsBridge.bridgeAndroidToJavaScript_MediaEvent(MediaEventType.SEEKED)
366
- }
367
- is TimeUpdateEvent -> {
368
- if (player.playing) {
369
- jsBridge.bridgeAndroidToJavaScript_MediaEvent(MediaEventType.TIME_UPDATE)
370
- }
371
- }
372
- is PauseEvent -> {
373
- if (!player.playing) {
374
- jsBridge.bridgeAndroidToJavaScript_MediaEvent(MediaEventType.PAUSE)
375
- }
376
- }
377
- is LoadedMetadataEvent,
378
- is AddAudioTrackEvent, is AddTextTrackEvent,
379
- is RemoveAudioTrackEvent, is RemoveTextTrackEvent,
380
- is ChangeAudioTrackEvent, is ChangeTextTrackEvent -> {
381
- Log.d("WebViewModel", "onTracksChanged: audio=$audioTrack subtitle=$subtitleTrack")
382
- jsBridge.bridgeAndroidToJavaScript_MediaTrackEvent(MediaEventType.TRACKS_CHANGED, player.audioTracks, player.textTracks)
383
- }
384
- }
385
- }
386
-
387
- fun setSubtitleTrack(track: TextTrack?) {
388
- player?.textTrack = track
389
- }
390
-
391
- fun setAudioTrack(track: AudioTrack?) {
392
- player?.audioTrack = track
393
- }
394
-
395
- fun saveToLocalStorage(key: String?, value: String?) {
396
- localStorage.saveCookieJson(key, value)
397
- }
398
-
399
- fun getFromLocalStorage(key: String?): String? {
400
- return localStorage.getFromLocalStorage(key)
401
- }
402
-
403
- fun removeFromLocalStorage(key: String?) {
404
- localStorage.removeFromLocalStorage(key)
405
- }
406
-
407
- fun sendKeyCode(keyCode: Int, mediaEventType: String) {
408
- jsBridge.bridgeAndroidToJavaScript_KeyEvent(keyCode, mediaEventType)
409
- }
410
-
411
- fun setPlaybackInfo(playbackInfo: AnalyticsPlaybackInfo) {
412
- if ("JUMP" == playbackInfo.name) {
413
- jumpAnalytics.setPlaybackInfo(playbackInfo)
414
- }
415
- }
416
-
417
- fun showMessage(message: String?) {
418
- view?.showMessage(message)
419
- }
420
-
421
- fun requestAudioFocus(): Int? {
422
- return view?.requestAudioFocus()
423
- }
424
-
425
- fun abandonAudioFocus() {
426
- view?.abandonAudioFocus()
427
- }
428
-
429
- fun onBackPressed() {
430
- stopPlayer()
431
- view?.onBackPressed()
432
- loadUrl(appUrl)
433
- }
434
-
435
- fun signData(dataJson: String?): String? {
436
- return if (dataJson == null || dataJson.isEmpty()) "" else Flavor().signData(context, dataJson)
437
- }
438
-
439
- fun launchIapPurchase(sku: String?) {
440
- if (sku == null || sku.isEmpty()) return
441
- view?.launchIapPurchase(sku)
442
- }
443
-
444
- fun checkNewPurchases() {
445
- iapService.setCallback(iapCallback)
446
- iapService.checkNewPurchases()
447
- }
448
-
449
- fun launchIapPurchase(activity: Activity, sku: String) {
450
- iapService.setCallback(iapCallback)
451
- iapService.purchase(activity, sku)
452
- }
453
-
454
- fun getIapProductDetails(skus: List<String>) {
455
- iapService.setCallback(iapCallback)
456
- iapService.getProducts(skus)
457
- }
458
-
459
- fun acknowledgeIapReceipt(receiptId: String) {
460
- iapService.setCallback(iapCallback)
461
- iapService.acknowledgeReceipt(receiptId)
462
- }
463
-
464
- private fun dispatchKeyEvent(event: KeyEvent): Boolean {
465
- // pause and stop events should be caught only when we are in player
466
- // -> because we want to let user have option to pause/stop some background playback
467
- if (isInPlayer) {
468
- // we have to catch all media events, otherwise they will be unhandled and reported in onUnhandledKeyEvent
469
- // -> and later sent to broadcast receivers of other media apps, which can resume stream/audio from background app
470
- when (event.keyCode) {
471
- KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE,
472
- KeyEvent.KEYCODE_MEDIA_STOP,
473
- KeyEvent.KEYCODE_MEDIA_PAUSE -> {
474
- if (event.action == KeyEvent.ACTION_DOWN) {
475
- jsBridge.bridgeAndroidToJavaScript_KeyEvent(event.keyCode, MediaEventType.KEY_DOWN)
476
- } else if (event.action == KeyEvent.ACTION_UP) {
477
- jsBridge.bridgeAndroidToJavaScript_KeyEvent(event.keyCode, MediaEventType.KEY_UP)
478
- }
479
- return true
480
- }
481
- }
482
- }
483
- when (event.keyCode) {
484
- KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK,
485
- KeyEvent.KEYCODE_MEDIA_CLOSE,
486
- KeyEvent.KEYCODE_MEDIA_EJECT,
487
- KeyEvent.KEYCODE_MEDIA_FAST_FORWARD,
488
- KeyEvent.KEYCODE_MEDIA_NEXT,
489
- KeyEvent.KEYCODE_MEDIA_PREVIOUS,
490
- KeyEvent.KEYCODE_MEDIA_RECORD,
491
- KeyEvent.KEYCODE_MEDIA_REWIND,
492
- KeyEvent.KEYCODE_MEDIA_SKIP_BACKWARD,
493
- KeyEvent.KEYCODE_MEDIA_SKIP_FORWARD,
494
- KeyEvent.KEYCODE_MEDIA_STEP_BACKWARD,
495
- KeyEvent.KEYCODE_MEDIA_STEP_FORWARD,
496
- KeyEvent.KEYCODE_MEDIA_TOP_MENU,
497
- KeyEvent.KEYCODE_MEDIA_PLAY -> {
498
- if (event.action == KeyEvent.ACTION_DOWN) {
499
- jsBridge.bridgeAndroidToJavaScript_KeyEvent(event.keyCode, MediaEventType.KEY_DOWN)
500
- } else if (event.action == KeyEvent.ACTION_UP) {
501
- jsBridge.bridgeAndroidToJavaScript_KeyEvent(event.keyCode, MediaEventType.KEY_UP)
502
- }
503
- return true
504
- }
505
- }
506
- return false
507
- }
508
-
509
- private inner class InnerIapCallback : IapCallback {
510
- override fun checkNewPurchasesFinished(result: List<IapPurchase>) {
511
- // not actually used at the moment
512
- }
513
-
514
- override fun checkNewPurchasesFinished(exception: Exception) {
515
- // not actually used at the moment
516
- }
517
-
518
- override fun purchaseFinished(result: IapPurchase) {
519
- jsBridge.bridgeAndroidToJavaScript_IAPValidationSuccess(result.userId, result.receipt, result.sku)
520
- }
521
-
522
- override fun purchaseFinished(exception: Exception) {
523
- if (exception is IapException) {
524
- jsBridge.bridgeAndroidToJavaScript_IAPValidationError(exception.status)
525
- } else {
526
- jsBridge.bridgeAndroidToJavaScript_IAPValidationError(exception.message
527
- ?: "Purchase failed")
528
- }
529
- }
530
-
531
- override fun getProductsFinished(result: List<IapProduct>, missing: List<String>) {
532
- val okSkus = JsonArray()
533
- for (iapProduct in result) {
534
- val jsonProduct = JsonObject()
535
- jsonProduct.addProperty("title", iapProduct.title)
536
- jsonProduct.addProperty("description", iapProduct.description)
537
- jsonProduct.addProperty("price", iapProduct.price)
538
- jsonProduct.addProperty("icon", iapProduct.icon)
539
- jsonProduct.addProperty("type", iapProduct.type)
540
- jsonProduct.addProperty("sku", iapProduct.sku)
541
- okSkus.add(jsonProduct)
542
- }
543
- val badSkus = JsonArray()
544
- for (sku in missing) {
545
- badSkus.add(sku)
546
- }
547
- jsBridge.bridgeIAPGetProductDataSuccess(okSkus.toString(), badSkus.toString())
548
- }
549
-
550
- override fun getProductsFinished(exception: Exception) {
551
- if (exception is IapException) {
552
- jsBridge.bridgeIAPGetProductDataFail(exception.status)
553
- } else {
554
- jsBridge.bridgeIAPGetProductDataFail(exception.message ?: "Purchase failed")
555
- }
556
- }
557
-
558
- override fun acknowledgeReceiptFinished(exception: Exception?) {
559
- // JS does not care
560
- }
561
- }
562
-
563
- companion object {
564
- const val JAVA_SCRIPT_BRIDGE = "JavaScriptBridge"
565
- const val LOW_END_DEVICE_MAX_BITRATE = 1500000
566
- val DISABLED_TEXT_TRACK = TextTrack {
567
- id = "text_off"
568
- kind = TrackKind.EMPTY
569
- }
570
- }
571
- }
@@ -1,10 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <shape xmlns:android="http://schemas.android.com/apk/res/android">
3
- <solid
4
- android:color="#E5F0FD"/>
5
- <stroke
6
- android:color="#33D7FF"
7
- android:width="3dp"/>
8
- <corners
9
- android:radius="5dp" />
10
- </shape>
@@ -1,7 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <shape xmlns:android="http://schemas.android.com/apk/res/android">
3
- <solid
4
- android:color="#E5F0FD"/>
5
- <corners
6
- android:radius="5dp" />
7
- </shape>
@@ -1,7 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <shape xmlns:android="http://schemas.android.com/apk/res/android">
3
- <solid
4
- android:color="#1FD3FF"/>
5
- <corners
6
- android:radius="5dp" />
7
- </shape>
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="utf-8"?>
2
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
3
- <item android:drawable="@drawable/button_background_pressed"
4
- android:state_pressed="true" />
5
- <item android:drawable="@drawable/button_background_focus"
6
- android:state_focused="true" />
7
- <item android:drawable="@drawable/button_background_normal"/>
8
- </selector>
@@ -1,76 +0,0 @@
1
- <layout xmlns:android="http://schemas.android.com/apk/res/android"
2
- xmlns:app="http://schemas.android.com/apk/res-auto"
3
- xmlns:tools="http://schemas.android.com/tools">
4
-
5
- <data>
6
-
7
- <variable
8
- name="viewModel"
9
- type="com.twentyfouri.tvbridge.webview.viewmodel.WebViewModel" />
10
- </data>
11
-
12
- <RelativeLayout
13
- android:layout_width="match_parent"
14
- android:layout_height="match_parent"
15
- android:background="@android:color/black"
16
- tools:context=".webview.ui.view.WebViewActivity">
17
-
18
- <com.twentyfouri.player.base.PlayerView
19
- android:id="@+id/exoplayer_view"
20
- android:layout_width="match_parent"
21
- android:layout_height="match_parent" />
22
-
23
- <View
24
- android:id="@+id/black_curtain"
25
- android:layout_width="match_parent"
26
- android:layout_height="match_parent"
27
- android:background="@android:color/black" />
28
-
29
- <LinearLayout
30
- android:id="@+id/url_setter"
31
- android:layout_width="match_parent"
32
- android:layout_height="wrap_content"
33
- android:layout_centerInParent="true"
34
- android:layout_margin="80dp"
35
- android:orientation="vertical"
36
- app:visibility="@{viewModel.urlSetterVisibility}">
37
-
38
- <EditText
39
- android:id="@+id/url"
40
- android:layout_width="match_parent"
41
- android:layout_height="wrap_content"
42
- android:nextFocusUp="@+id/url"
43
- android:nextFocusLeft="@+id/url"
44
- android:nextFocusRight="@+id/url"
45
- android:textColor="@android:color/white"/>
46
-
47
- <Button
48
- android:id="@+id/button_go"
49
- android:layout_width="100dp"
50
- android:layout_height="wrap_content"
51
- android:background="@drawable/button_focus"
52
- android:textColor="@android:color/black"
53
- android:nextFocusDown="@+id/button_go"
54
- android:nextFocusLeft="@+id/button_go"
55
- android:nextFocusRight="@+id/button_go"
56
- android:onClick="@{() -> viewModel.onClickGo()}"
57
- android:text="GO" />
58
-
59
- </LinearLayout>
60
-
61
- <com.twentyfouri.tvbridge.webview.client.BridgeWebView
62
- android:id="@+id/webview"
63
- android:layout_width="match_parent"
64
- android:layout_height="match_parent"
65
- android:layout_alignParentBottom="true"
66
- android:layout_alignParentEnd="true"
67
- android:layout_alignParentStart="true"
68
- android:layout_alignParentTop="true"
69
- android:background="@android:color/transparent"
70
- android:visibility="gone"/>
71
-
72
- </RelativeLayout>
73
-
74
- </layout>
75
-
76
-