连续多天,我一直在尝试在我的 FireTV 棒上的 WebView 中运行直播。 我完全陷入困境,非常感谢我能得到的任何帮助。
所示网站在我的测试设备上的标准浏览器中完美运行。 我已经成功解决了所有 DRM 问题,并且能够听到加密的声音。 但从视觉上看,什么也没有。我无法找到任何与此相关的资源。指南总是停在媒体播放的地方。而且我在谷歌搜索时可能错过了一些重要的关键字,因为我实际上找不到类似的案例。
我尝试解决这个问题,并开始在位于 WebView 后面的 exoplayer 实例中运行我的直播。效果非常好。 但后来我注意到,在调用 exoplayer 实例上的 .prepare() 函数后,WebView 中的视频元素开始播放视觉效果。所以我检查了最新版本的exoplayer。遗憾的是,我无法识别 exoplayer 为在 WebView 中正确播放而执行的任何特定操作。 你知道可能缺少什么吗?
<RelativeLayout>
<FrameLayout/>
<WebView/>
</RelativeLayout>
class MyWebChromeClient : WebChromeClient() {
override fun onPermissionRequest(request: PermissionRequest?) {
request?.let {
it.grant(it.resources)
}
}
}
class MyWebViewClient() : WebViewClient() {
override fun onReceiveSslError(view: WebView?, handler: SslErrorHandler, error: SslError?) {
handler.proceed()
}
override fun shouldOverrideUrlLoading(view: WebView, url: String?): Boolean {
view.loadUrl(url!!)
return true
}
}
class MainActivity : ComponentActivity() {
private lateinit var myWebView: WebView
private lateinit var exoPlayer: ExoPlayer
private lateinit var belowFrame: FrameLayout
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
belowFrame = findViewById(R.id.exo_below) as FrameLayout
myWebView = findViewById(R.id.webview) as WebView
exoPlayer = ExoPlayer.Builder(this).build()
val belowView = PlayerView(this)
belowView.player = exoPlayer
belowFrame.addView(belowView)
myWebView.setWebViewClient(MyWebViewClient())
myWebView.setWebChromeClient(MyWebChromeClient())
myWebView.settings.javaScriptEnabled = true
myWebView.settings.javaScriptCanOpenWindowsAutomatically = true
myWebView.settings.allowContentAccess = true
myWebView.settings.domStorageEnabled = true
myWebView.settings.mediaPlaybackRequiresUserGesture = false
myWebView.settings.allowFileAccess = true
myWebView.setLayerType(View.LAYER_TYPE_HARDWARE, null)
myWebView.setInitialScale(100)
myWebView.loadUrl("localhost:3000")
myWebView.requestFocus()
}
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK) {
myWebView.evaluateJavascript("document.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 8 }))", null)
return true
}
}
// this is called via javascript interface
fun onVideoStart(videoUrl: String) {
runBlocking(Dispatchers.Main.immedate)
{
val
mediaSource = buildMediaSource("http://mcdn.daserste.de/daserste/dash/manifest.mpd")
exoPlayer.setMediaSource(mediaSource)
exoPlayer.prepare() // <= this step makes WebView videos play as expected
}
}
fun buildMediaSource(videoUrl: String): MediaSource {
val dataSourceFactory = DefaultHttpDataSource.Factory()
return DashMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(videoUrl))
}
}
我已将以下权限添加到清单中: android.permission.INTERNET android.permission.ACCESS_NETWORK_STATE android.permission.RESOURCE_PROTECTED_MEDIA_ID`
minSdk = 25
targetSdk = 34
compileSdk = 34
在对这个主题进行了大量阅读并查看大量日志后,我找到了答案。
事实证明,您需要在 WebView 下方放置一个 SurfaceView。 据我所知,在哪里并不重要。 所有视频播放器似乎都自己创建或继承这样的视图。但本机 WebView 由于某种原因跳过了这一点。
添加 Surfaceview 后,WebView 中的视频将可见。