安卓ExoPlayer如何播放私人Vimeo视频

4

我正在尝试使用ExoPlayer播放Vimeo视频,以下是代码:

val dataSourceFactory = DefaultDataSourceFactory(requireContext(),
                getUserAgent(requireContext(), requireContext().getString(R.string.app_name)))
val videoSource = ProgressiveMediaSource.Factory(dataSourceFactory)
                .createMediaSource(Uri.parse(videoLink))
player.prepare(videoSource)

这将抛出以下异常:
com.google.android.exoplayer2.upstream.HttpDataSource$InvalidResponseCodeException: Response code: 403
        at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:300)
        at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:177)
        at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:83)
        at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:961)
        at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:391)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
        at java.lang.Thread.run(Thread.java:764)

我尝试使用AndroidVimeoExtractor提取Vimeo URL,但是出现了以下异常:

java.io.IOException: Video has restricted playback

这里是代码:

VimeoExtractor.getInstance().fetchVideoWithIdentifier(
                "videoIdentifier",
                null,
                object : OnVimeoExtractionListener {
                    override fun onSuccess(video: VimeoVideo) {
                        Logger.i("video: ${video.streams.size}")
                    }

                    override fun onFailure(throwable: Throwable) {
                        Logger.e(throwable)
                    }

                })

以下是Vimeo视频链接示例:http://player.vimeo.com/external/videoIdentifier.sd.mp4?s=value&profile_id=value&oauth2_token_id=value

注意:我不是上传该视频的人。此外,当我在Google Chrome浏览器中输入链接时,它会重定向到另一个链接并正常播放视频。因此,我需要类似的方法来获取最终链接以将其传递给ExoPlayer


首先,非常感谢您尝试使用我的库!看到人们使用它很酷 :)然而,这个库已经不再维护了。我想 Vimeo 自我上次更新以来可能已经显著改变了他们的 API。也许有一天我会回来看看它,但现在我建议您找到另一种替代方法 :) - Ed Holloway-George
2个回答

1

有两种方法来解决这个问题

第一种解决方案

  • 使用Vimeo networking API获得视频URI并使用它
  • vimeo developer上创建应用程序
  • 使用您的应用程序访问令牌和视频ID,您可以获取视频URL,然后将其传递给Exo播放器

第二种解决方案(这是一个变通和快速的解决方案)

  • 使用Web视图重定向到.mp4网址,然后使用以.mp4结尾的重定向网址打开Exo播放器

     webView = WebView(context).apply {
            settings.javaScriptEnabled = false
            webViewClient = object : WebViewClient() {
                override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
                    val requestUrl = request?.url.toString()
                    val uri = requestUrl.toUri()
                    if (isVideoLink(requestUrl)) {
                        preparePlayer(uri)
                        webView?.release()
                        webView = null
                        return true
                    }
                    return false
                }
            }
            loadUrl(url)
    }
    
    fun isVideoLink(url: String): Boolean {
        return getMimeType(url)?.contains("video", true) ?: false
    }


0
你是想播放所有 Vimeo 视频,还是只有你上传的 Vimeo 视频?
我认为问题在于你拉取的 mp4 文件实际上无效或由于 OAuth 令牌权限不足,你无法流式传输它(如果你不拥有它)。
你可以查看 vimeo-networking 库的 README here
The basic requirements for native playback are:

User must be logged in.
User must be the owner of the video.
User must be PRO or higher (or the app must have the "can access owner's video files" capability).
Token must have the video_files scope.
User must be the owner of the API app making the request.

如果您满足所有这些要求,那么您可以向 Vimeo 发送 API 请求,他们会返回一个有效的 MP4 文件,您可以将其作为 videoLink 传递。
// Obtain a video you own my making a GET request
Video video = ...;
Play play = video.getPlay();
// This will be a list of "progressive" video files (basically just MP4s of different resolutions that you can pass to ExoPlayer
ArrayList<VideoFile> progressiveFiles = play.getProgressiveVideoFiles();
String linkToMp4File = progressiveFiles.get(0).getLink();
val videoSource = ProgressiveMediaSource.Factory(dataSourceFactory)
                .createMediaSource(Uri.parse(linkToMp4File))

如果您不是上传视频的人,我认为有一种方法可以获得有效的视频链接,但我个人从未尝试过。由于所有用户都可以嵌入任何视频(如果视频是公共的且可嵌入的),因此您可以从API here获取嵌入链接,然后从嵌入代码中提取MP4文件链接,也许可以这样做?只是一个想法。


我的建议是最后可能能帮到你。你应该能够从中获取嵌入链接和流。 - Kyle Venn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接