mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-08-04 07:09:53 +00:00
add raw dash audio source widevine support
This commit is contained in:
parent
1b8b8f5738
commit
6ec033274f
7 changed files with 120 additions and 46 deletions
|
@ -372,7 +372,7 @@ class VideoUrlWidevineSource extends VideoUrlSource {
|
||||||
super(obj);
|
super(obj);
|
||||||
this.plugin_type = "VideoUrlWidevineSource";
|
this.plugin_type = "VideoUrlWidevineSource";
|
||||||
|
|
||||||
this.licenseUri = obj.licenseUri;
|
this.widevineLicenseUri = obj.licenseUri;
|
||||||
if(obj.getLicenseRequestExecutor)
|
if(obj.getLicenseRequestExecutor)
|
||||||
this.getLicenseRequestExecutor = obj.getLicenseRequestExecutor;
|
this.getLicenseRequestExecutor = obj.getLicenseRequestExecutor;
|
||||||
}
|
}
|
||||||
|
@ -409,7 +409,7 @@ class AudioUrlWidevineSource extends AudioUrlSource {
|
||||||
super(obj);
|
super(obj);
|
||||||
this.plugin_type = "AudioUrlWidevineSource";
|
this.plugin_type = "AudioUrlWidevineSource";
|
||||||
|
|
||||||
this.licenseUri = obj.licenseUri;
|
this.widevineLicenseUri = obj.licenseUri;
|
||||||
if(obj.getLicenseRequestExecutor)
|
if(obj.getLicenseRequestExecutor)
|
||||||
this.getLicenseRequestExecutor = obj.getLicenseRequestExecutor;
|
this.getLicenseRequestExecutor = obj.getLicenseRequestExecutor;
|
||||||
|
|
||||||
|
@ -469,6 +469,8 @@ class DashSource {
|
||||||
this.language = obj.language;
|
this.language = obj.language;
|
||||||
if(obj.requestModifier)
|
if(obj.requestModifier)
|
||||||
this.requestModifier = obj.requestModifier;
|
this.requestModifier = obj.requestModifier;
|
||||||
|
if(obj.getRequestExecutor)
|
||||||
|
this.getRequestExecutor = obj.getRequestExecutor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class DashWidevineSource extends DashSource {
|
class DashWidevineSource extends DashSource {
|
||||||
|
@ -476,7 +478,7 @@ class DashWidevineSource extends DashSource {
|
||||||
super(obj);
|
super(obj);
|
||||||
this.plugin_type = "DashWidevineSource";
|
this.plugin_type = "DashWidevineSource";
|
||||||
|
|
||||||
this.licenseUri = obj.licenseUri;
|
this.widevineLicenseUri = obj.licenseUri;
|
||||||
if(obj.getLicenseRequestExecutor)
|
if(obj.getLicenseRequestExecutor)
|
||||||
this.getLicenseRequestExecutor = obj.getLicenseRequestExecutor;
|
this.getLicenseRequestExecutor = obj.getLicenseRequestExecutor;
|
||||||
}
|
}
|
||||||
|
@ -511,6 +513,9 @@ class DashManifestRawAudioSource {
|
||||||
this.manifest = obj.manifest ?? null;
|
this.manifest = obj.manifest ?? null;
|
||||||
if(obj.requestModifier)
|
if(obj.requestModifier)
|
||||||
this.requestModifier = obj.requestModifier;
|
this.requestModifier = obj.requestModifier;
|
||||||
|
this.widevineLicenseUri = obj.widevineLicenseUri;
|
||||||
|
if(obj.getLicenseRequestExecutor)
|
||||||
|
this.getLicenseRequestExecutor = obj.getLicenseRequestExecutor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.futo.platformplayer.api.media.models.streams.sources
|
||||||
import com.futo.platformplayer.api.media.platforms.js.models.JSRequestExecutor
|
import com.futo.platformplayer.api.media.platforms.js.models.JSRequestExecutor
|
||||||
|
|
||||||
interface IWidevineSource {
|
interface IWidevineSource {
|
||||||
val licenseUri: String
|
val widevineLicenseUri: String?
|
||||||
val hasLicenseRequestExecutor: Boolean
|
val hasLicenseRequestExecutor: Boolean
|
||||||
fun getLicenseRequestExecutor(): JSRequestExecutor?
|
fun getLicenseRequestExecutor(): JSRequestExecutor?
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@ import com.futo.platformplayer.engine.V8Plugin
|
||||||
import com.futo.platformplayer.getOrThrow
|
import com.futo.platformplayer.getOrThrow
|
||||||
|
|
||||||
class JSAudioUrlWidevineSource : JSAudioUrlSource, IAudioUrlWidevineSource {
|
class JSAudioUrlWidevineSource : JSAudioUrlSource, IAudioUrlWidevineSource {
|
||||||
override val licenseUri: String
|
override val widevineLicenseUri: String
|
||||||
override val hasLicenseRequestExecutor: Boolean
|
override val hasLicenseRequestExecutor: Boolean
|
||||||
|
|
||||||
@Suppress("ConvertSecondaryConstructorToPrimary")
|
@Suppress("ConvertSecondaryConstructorToPrimary")
|
||||||
|
@ -16,7 +16,7 @@ class JSAudioUrlWidevineSource : JSAudioUrlSource, IAudioUrlWidevineSource {
|
||||||
val contextName = "JSAudioUrlWidevineSource"
|
val contextName = "JSAudioUrlWidevineSource"
|
||||||
val config = plugin.config
|
val config = plugin.config
|
||||||
|
|
||||||
licenseUri = _obj.getOrThrow(config, "licenseUri", contextName)
|
widevineLicenseUri = _obj.getOrThrow(config, "widevineLicenseUri", contextName)
|
||||||
hasLicenseRequestExecutor = obj.has("getLicenseRequestExecutor")
|
hasLicenseRequestExecutor = obj.has("getLicenseRequestExecutor")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,6 @@ class JSAudioUrlWidevineSource : JSAudioUrlSource, IAudioUrlWidevineSource {
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
val url = getAudioUrl()
|
val url = getAudioUrl()
|
||||||
return "(name=$name, container=$container, bitrate=$bitrate, codec=$codec, url=$url, language=$language, duration=$duration, hasLicenseRequestExecutor=${hasLicenseRequestExecutor}, licenseUri=$licenseUri)"
|
return "(name=$name, container=$container, bitrate=$bitrate, codec=$codec, url=$url, language=$language, duration=$duration, hasLicenseRequestExecutor=${hasLicenseRequestExecutor}, widevineLicenseUri=$widevineLicenseUri)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,19 +2,17 @@ package com.futo.platformplayer.api.media.platforms.js.models.sources
|
||||||
|
|
||||||
import com.caoccao.javet.values.reference.V8ValueObject
|
import com.caoccao.javet.values.reference.V8ValueObject
|
||||||
import com.futo.platformplayer.api.media.models.streams.sources.IAudioSource
|
import com.futo.platformplayer.api.media.models.streams.sources.IAudioSource
|
||||||
import com.futo.platformplayer.api.media.models.streams.sources.IDashManifestSource
|
import com.futo.platformplayer.api.media.models.streams.sources.IWidevineSource
|
||||||
import com.futo.platformplayer.api.media.models.streams.sources.IVideoUrlSource
|
|
||||||
import com.futo.platformplayer.api.media.platforms.js.DevJSClient
|
import com.futo.platformplayer.api.media.platforms.js.DevJSClient
|
||||||
import com.futo.platformplayer.api.media.platforms.js.JSClient
|
import com.futo.platformplayer.api.media.platforms.js.JSClient
|
||||||
import com.futo.platformplayer.engine.IV8PluginConfig
|
import com.futo.platformplayer.api.media.platforms.js.models.JSRequestExecutor
|
||||||
import com.futo.platformplayer.engine.V8Plugin
|
import com.futo.platformplayer.engine.V8Plugin
|
||||||
import com.futo.platformplayer.getOrDefault
|
import com.futo.platformplayer.getOrDefault
|
||||||
import com.futo.platformplayer.getOrNull
|
|
||||||
import com.futo.platformplayer.getOrThrow
|
import com.futo.platformplayer.getOrThrow
|
||||||
import com.futo.platformplayer.others.Language
|
import com.futo.platformplayer.others.Language
|
||||||
import com.futo.platformplayer.states.StateDeveloper
|
import com.futo.platformplayer.states.StateDeveloper
|
||||||
|
|
||||||
class JSDashManifestRawAudioSource : JSSource, IAudioSource, IJSDashManifestRawSource {
|
class JSDashManifestRawAudioSource : JSSource, IAudioSource, IJSDashManifestRawSource, IWidevineSource {
|
||||||
override val container : String = "application/dash+xml";
|
override val container : String = "application/dash+xml";
|
||||||
override val name : String;
|
override val name : String;
|
||||||
override val codec: String;
|
override val codec: String;
|
||||||
|
@ -29,6 +27,9 @@ class JSDashManifestRawAudioSource : JSSource, IAudioSource, IJSDashManifestRawS
|
||||||
|
|
||||||
override val hasGenerate: Boolean;
|
override val hasGenerate: Boolean;
|
||||||
|
|
||||||
|
override val widevineLicenseUri: String?
|
||||||
|
override val hasLicenseRequestExecutor: Boolean
|
||||||
|
|
||||||
constructor(plugin: JSClient, obj: V8ValueObject) : super(TYPE_DASH_RAW, plugin, obj) {
|
constructor(plugin: JSClient, obj: V8ValueObject) : super(TYPE_DASH_RAW, plugin, obj) {
|
||||||
val contextName = "DashRawSource";
|
val contextName = "DashRawSource";
|
||||||
val config = plugin.config;
|
val config = plugin.config;
|
||||||
|
@ -41,6 +42,23 @@ class JSDashManifestRawAudioSource : JSSource, IAudioSource, IJSDashManifestRawS
|
||||||
priority = _obj.getOrDefault(config, "priority", contextName, false) ?: false;
|
priority = _obj.getOrDefault(config, "priority", contextName, false) ?: false;
|
||||||
language = _obj.getOrDefault(config, "language", contextName, Language.UNKNOWN) ?: Language.UNKNOWN;
|
language = _obj.getOrDefault(config, "language", contextName, Language.UNKNOWN) ?: Language.UNKNOWN;
|
||||||
hasGenerate = _obj.has("generate");
|
hasGenerate = _obj.has("generate");
|
||||||
|
|
||||||
|
widevineLicenseUri = _obj.getOrThrow(config, "widevineLicenseUri", contextName)
|
||||||
|
hasLicenseRequestExecutor = obj.has("getLicenseRequestExecutor")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLicenseRequestExecutor(): JSRequestExecutor? {
|
||||||
|
if (!hasLicenseRequestExecutor || _obj.isClosed)
|
||||||
|
return null
|
||||||
|
|
||||||
|
val result = V8Plugin.catchScriptErrors<Any>(_config, "[${_config.name}] JSDashManifestRawAudioSource", "obj.getLicenseRequestExecutor()") {
|
||||||
|
_obj.invoke("getLicenseRequestExecutor", arrayOf<Any>())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result !is V8ValueObject)
|
||||||
|
return null
|
||||||
|
|
||||||
|
return JSRequestExecutor(_plugin, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun generate(): String? {
|
override fun generate(): String? {
|
||||||
|
|
|
@ -23,7 +23,7 @@ class JSDashManifestWidevineSource : IVideoUrlSource, IDashManifestSource,
|
||||||
|
|
||||||
override var priority: Boolean = false
|
override var priority: Boolean = false
|
||||||
|
|
||||||
override val licenseUri: String
|
override val widevineLicenseUri: String
|
||||||
override val hasLicenseRequestExecutor: Boolean
|
override val hasLicenseRequestExecutor: Boolean
|
||||||
|
|
||||||
@Suppress("ConvertSecondaryConstructorToPrimary")
|
@Suppress("ConvertSecondaryConstructorToPrimary")
|
||||||
|
@ -36,7 +36,7 @@ class JSDashManifestWidevineSource : IVideoUrlSource, IDashManifestSource,
|
||||||
|
|
||||||
priority = obj.getOrNull(config, "priority", contextName) ?: false
|
priority = obj.getOrNull(config, "priority", contextName) ?: false
|
||||||
|
|
||||||
licenseUri = _obj.getOrThrow(config, "licenseUri", contextName)
|
widevineLicenseUri = _obj.getOrThrow(config, "widevineLicenseUri", contextName)
|
||||||
hasLicenseRequestExecutor = obj.has("getLicenseRequestExecutor")
|
hasLicenseRequestExecutor = obj.has("getLicenseRequestExecutor")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import com.futo.platformplayer.engine.V8Plugin
|
||||||
import com.futo.platformplayer.getOrThrow
|
import com.futo.platformplayer.getOrThrow
|
||||||
|
|
||||||
class JSVideoUrlWidevineSource : JSVideoUrlSource, IVideoUrlWidevineSource {
|
class JSVideoUrlWidevineSource : JSVideoUrlSource, IVideoUrlWidevineSource {
|
||||||
override val licenseUri: String
|
override val widevineLicenseUri: String
|
||||||
override val hasLicenseRequestExecutor: Boolean
|
override val hasLicenseRequestExecutor: Boolean
|
||||||
|
|
||||||
@Suppress("ConvertSecondaryConstructorToPrimary")
|
@Suppress("ConvertSecondaryConstructorToPrimary")
|
||||||
|
@ -16,7 +16,7 @@ class JSVideoUrlWidevineSource : JSVideoUrlSource, IVideoUrlWidevineSource {
|
||||||
val contextName = "JSAudioUrlWidevineSource"
|
val contextName = "JSAudioUrlWidevineSource"
|
||||||
val config = plugin.config
|
val config = plugin.config
|
||||||
|
|
||||||
licenseUri = _obj.getOrThrow(config, "licenseUri", contextName)
|
widevineLicenseUri = _obj.getOrThrow(config, "widevineLicenseUri", contextName)
|
||||||
hasLicenseRequestExecutor = obj.has("getLicenseRequestExecutor")
|
hasLicenseRequestExecutor = obj.has("getLicenseRequestExecutor")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,6 @@ class JSVideoUrlWidevineSource : JSVideoUrlSource, IVideoUrlWidevineSource {
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
val url = getVideoUrl()
|
val url = getVideoUrl()
|
||||||
return "(width=$width, height=$height, container=$container, codec=$codec, name=$name, bitrate=$bitrate, duration=$duration, url=$url, hasLicenseRequestExecutor=$hasLicenseRequestExecutor, licenseUri=$licenseUri)"
|
return "(width=$width, height=$height, container=$container, codec=$codec, name=$name, bitrate=$bitrate, duration=$duration, url=$url, hasLicenseRequestExecutor=$hasLicenseRequestExecutor, widevineLicenseUri=$widevineLicenseUri)"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package com.futo.platformplayer.views.video
|
package com.futo.platformplayer.views.video
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.media.MediaDrm
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.widget.RelativeLayout
|
import android.widget.RelativeLayout
|
||||||
|
@ -57,8 +58,8 @@ import com.futo.platformplayer.helpers.VideoHelper
|
||||||
import com.futo.platformplayer.logging.Logger
|
import com.futo.platformplayer.logging.Logger
|
||||||
import com.futo.platformplayer.states.StateApp
|
import com.futo.platformplayer.states.StateApp
|
||||||
import com.futo.platformplayer.video.PlayerManager
|
import com.futo.platformplayer.video.PlayerManager
|
||||||
import com.futo.platformplayer.views.video.datasources.PluginMediaDrmCallback
|
|
||||||
import com.futo.platformplayer.views.video.datasources.JSHttpDataSource
|
import com.futo.platformplayer.views.video.datasources.JSHttpDataSource
|
||||||
|
import com.futo.platformplayer.views.video.datasources.PluginMediaDrmCallback
|
||||||
import getHttpDataSourceFactory
|
import getHttpDataSourceFactory
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -483,15 +484,20 @@ abstract class FutoVideoPlayerBase : RelativeLayout {
|
||||||
@OptIn(UnstableApi::class)
|
@OptIn(UnstableApi::class)
|
||||||
private fun swapVideoSourceUrlWidevine(videoSource: IVideoUrlWidevineSource) {
|
private fun swapVideoSourceUrlWidevine(videoSource: IVideoUrlWidevineSource) {
|
||||||
Logger.i(TAG, "Loading VideoSource [UrlWidevine]");
|
Logger.i(TAG, "Loading VideoSource [UrlWidevine]");
|
||||||
|
|
||||||
|
if (!MediaDrm.isCryptoSchemeSupported(C.WIDEVINE_UUID)) {
|
||||||
|
throw IllegalArgumentException("Device does not support Widevine")
|
||||||
|
}
|
||||||
|
|
||||||
val dataSource = if(videoSource is JSSource && videoSource.requiresCustomDatasource)
|
val dataSource = if(videoSource is JSSource && videoSource.requiresCustomDatasource)
|
||||||
videoSource.getHttpDataSourceFactory()
|
videoSource.getHttpDataSourceFactory()
|
||||||
else
|
else
|
||||||
DefaultHttpDataSource.Factory().setUserAgent(DEFAULT_USER_AGENT)
|
DefaultHttpDataSource.Factory().setUserAgent(DEFAULT_USER_AGENT)
|
||||||
|
|
||||||
val baseCallback = HttpMediaDrmCallback(videoSource.licenseUri, dataSource)
|
val baseCallback = HttpMediaDrmCallback(videoSource.widevineLicenseUri, dataSource)
|
||||||
|
|
||||||
val callback = if (videoSource.hasLicenseRequestExecutor) {
|
val callback = if (videoSource.hasLicenseRequestExecutor) {
|
||||||
PluginMediaDrmCallback(baseCallback, videoSource.getLicenseRequestExecutor()!!, videoSource.licenseUri)
|
PluginMediaDrmCallback(baseCallback, videoSource.getLicenseRequestExecutor()!!, videoSource.widevineLicenseUri!!)
|
||||||
} else {
|
} else {
|
||||||
baseCallback
|
baseCallback
|
||||||
}
|
}
|
||||||
|
@ -519,14 +525,19 @@ abstract class FutoVideoPlayerBase : RelativeLayout {
|
||||||
@OptIn(UnstableApi::class)
|
@OptIn(UnstableApi::class)
|
||||||
private fun swapVideoSourceDashWidevine(videoSource: IDashManifestWidevineSource) {
|
private fun swapVideoSourceDashWidevine(videoSource: IDashManifestWidevineSource) {
|
||||||
Logger.i(TAG, "Loading VideoSource [DashWidevine]")
|
Logger.i(TAG, "Loading VideoSource [DashWidevine]")
|
||||||
|
|
||||||
|
if (!MediaDrm.isCryptoSchemeSupported(C.WIDEVINE_UUID)) {
|
||||||
|
throw IllegalArgumentException("Device does not support Widevine")
|
||||||
|
}
|
||||||
|
|
||||||
val dataSource =
|
val dataSource =
|
||||||
if (videoSource is JSSource && (videoSource.requiresCustomDatasource)) videoSource.getHttpDataSourceFactory()
|
if (videoSource is JSSource && (videoSource.requiresCustomDatasource)) videoSource.getHttpDataSourceFactory()
|
||||||
else DefaultHttpDataSource.Factory().setUserAgent(DEFAULT_USER_AGENT)
|
else DefaultHttpDataSource.Factory().setUserAgent(DEFAULT_USER_AGENT)
|
||||||
|
|
||||||
val baseCallback = HttpMediaDrmCallback(videoSource.licenseUri, dataSource)
|
val baseCallback = HttpMediaDrmCallback(videoSource.widevineLicenseUri, dataSource)
|
||||||
|
|
||||||
val callback = if (videoSource.hasLicenseRequestExecutor) {
|
val callback = if (videoSource.hasLicenseRequestExecutor) {
|
||||||
PluginMediaDrmCallback(baseCallback, videoSource.getLicenseRequestExecutor()!!, videoSource.licenseUri)
|
PluginMediaDrmCallback(baseCallback, videoSource.getLicenseRequestExecutor()!!, videoSource.widevineLicenseUri!!)
|
||||||
} else {
|
} else {
|
||||||
baseCallback
|
baseCallback
|
||||||
}
|
}
|
||||||
|
@ -651,49 +662,89 @@ abstract class FutoVideoPlayerBase : RelativeLayout {
|
||||||
|
|
||||||
@OptIn(UnstableApi::class)
|
@OptIn(UnstableApi::class)
|
||||||
private fun swapAudioSourceDashRaw(audioSource: JSDashManifestRawAudioSource, play: Boolean, resume: Boolean): Boolean {
|
private fun swapAudioSourceDashRaw(audioSource: JSDashManifestRawAudioSource, play: Boolean, resume: Boolean): Boolean {
|
||||||
Logger.i(TAG, "Loading AudioSource [DashRaw]");
|
Logger.i(TAG, "Loading AudioSource [DashRaw]")
|
||||||
val dataSource = if(audioSource is JSSource && (audioSource.requiresCustomDatasource))
|
val dataSource = if (audioSource.requiresCustomDatasource)
|
||||||
audioSource.getHttpDataSourceFactory()
|
audioSource.getHttpDataSourceFactory()
|
||||||
else
|
else
|
||||||
DefaultHttpDataSource.Factory().setUserAgent(DEFAULT_USER_AGENT);
|
DefaultHttpDataSource.Factory().setUserAgent(DEFAULT_USER_AGENT)
|
||||||
|
|
||||||
|
val baseCallback = HttpMediaDrmCallback(audioSource.widevineLicenseUri, dataSource)
|
||||||
|
|
||||||
|
val callback =
|
||||||
|
if (audioSource.hasLicenseRequestExecutor && audioSource.widevineLicenseUri != null) {
|
||||||
|
PluginMediaDrmCallback(baseCallback, audioSource.getLicenseRequestExecutor()!!, audioSource.widevineLicenseUri)
|
||||||
|
} else {
|
||||||
|
baseCallback
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastVideoMediaSource = DashMediaSource.Factory(dataSource).setDrmSessionManagerProvider {
|
||||||
|
DefaultDrmSessionManager.Builder().setMultiSession(true).build(callback)
|
||||||
|
}.createMediaSource(MediaItem.fromUri(audioSource.url))
|
||||||
|
|
||||||
if (audioSource.hasGenerate) {
|
if (audioSource.hasGenerate) {
|
||||||
findViewTreeLifecycleOwner()?.lifecycle?.coroutineScope?.launch(Dispatchers.IO) {
|
findViewTreeLifecycleOwner()?.lifecycle?.coroutineScope?.launch(Dispatchers.IO) {
|
||||||
val generated = audioSource.generate();
|
val generated = audioSource.generate()
|
||||||
if (generated != null) {
|
if (generated != null) {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
_lastVideoMediaSource = DashMediaSource.Factory(dataSource)
|
val factory = DashMediaSource.Factory(dataSource)
|
||||||
.createMediaSource(DashManifestParser().parse(Uri.parse(audioSource.url),
|
if (audioSource.widevineLicenseUri != null) {
|
||||||
ByteArrayInputStream(generated?.toByteArray() ?: ByteArray(0))));
|
if (!MediaDrm.isCryptoSchemeSupported(C.WIDEVINE_UUID)) {
|
||||||
loadSelectedSources(play, resume);
|
throw IllegalArgumentException("Device does not support Widevine")
|
||||||
|
}
|
||||||
|
factory.setDrmSessionManagerProvider {
|
||||||
|
DefaultDrmSessionManager.Builder().setMultiSession(true)
|
||||||
|
.build(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_lastVideoMediaSource = factory.createMediaSource(
|
||||||
|
DashManifestParser().parse(
|
||||||
|
Uri.parse(audioSource.url),
|
||||||
|
ByteArrayInputStream(generated.toByteArray() ?: ByteArray(0))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
loadSelectedSources(play, resume)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false
|
||||||
|
} else {
|
||||||
|
val factory = DashMediaSource.Factory(dataSource)
|
||||||
|
if (audioSource.widevineLicenseUri != null) {
|
||||||
|
if (!MediaDrm.isCryptoSchemeSupported(C.WIDEVINE_UUID)) {
|
||||||
|
throw IllegalArgumentException("Device does not support Widevine")
|
||||||
}
|
}
|
||||||
else {
|
factory.setDrmSessionManagerProvider {
|
||||||
_lastVideoMediaSource = DashMediaSource.Factory(dataSource)
|
DefaultDrmSessionManager.Builder().setMultiSession(true)
|
||||||
.createMediaSource(
|
.build(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_lastVideoMediaSource = factory.createMediaSource(
|
||||||
DashManifestParser().parse(
|
DashManifestParser().parse(
|
||||||
Uri.parse(audioSource.url),
|
Uri.parse(audioSource.url),
|
||||||
ByteArrayInputStream(audioSource.manifest?.toByteArray() ?: ByteArray(0))
|
ByteArrayInputStream(audioSource.manifest?.toByteArray() ?: ByteArray(0))
|
||||||
)
|
)
|
||||||
);
|
)
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(UnstableApi::class)
|
@OptIn(UnstableApi::class)
|
||||||
private fun swapAudioSourceUrlWidevine(audioSource: IAudioUrlWidevineSource) {
|
private fun swapAudioSourceUrlWidevine(audioSource: IAudioUrlWidevineSource) {
|
||||||
Logger.i(TAG, "Loading AudioSource [UrlWidevine]")
|
Logger.i(TAG, "Loading AudioSource [UrlWidevine]")
|
||||||
|
|
||||||
|
if (!MediaDrm.isCryptoSchemeSupported(C.WIDEVINE_UUID)) {
|
||||||
|
throw IllegalArgumentException("Device does not support Widevine")
|
||||||
|
}
|
||||||
|
|
||||||
val dataSource = if (audioSource is JSSource && audioSource.requiresCustomDatasource)
|
val dataSource = if (audioSource is JSSource && audioSource.requiresCustomDatasource)
|
||||||
audioSource.getHttpDataSourceFactory()
|
audioSource.getHttpDataSourceFactory()
|
||||||
else
|
else
|
||||||
DefaultHttpDataSource.Factory().setUserAgent(DEFAULT_USER_AGENT)
|
DefaultHttpDataSource.Factory().setUserAgent(DEFAULT_USER_AGENT)
|
||||||
|
|
||||||
val baseCallback = HttpMediaDrmCallback(audioSource.licenseUri, dataSource)
|
val baseCallback = HttpMediaDrmCallback(audioSource.widevineLicenseUri, dataSource)
|
||||||
|
|
||||||
val callback = if (audioSource.hasLicenseRequestExecutor) {
|
val callback = if (audioSource.hasLicenseRequestExecutor) {
|
||||||
PluginMediaDrmCallback(baseCallback, audioSource.getLicenseRequestExecutor()!!, audioSource.licenseUri)
|
PluginMediaDrmCallback(baseCallback, audioSource.getLicenseRequestExecutor()!!, audioSource.widevineLicenseUri!!)
|
||||||
} else {
|
} else {
|
||||||
baseCallback
|
baseCallback
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue