Android ExoPlayer播放私人Vimeo视频

时间:2020-02-11 15:02:59

标签: android video-streaming uri vimeo exoplayer

我正在尝试使用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网址,但失败,但出现以下异常:

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 Browser中时,它会重定向到另一个链接并正常播放视频。因此,我需要类似的方法来获取最终链接以将其传递给ExoPlayer

2 个答案:

答案 0 :(得分:1)

有两种方法可以解决这个问题

第一个解决方案

  • 使用 Vimeo 网络 API a link 获取视频 URI 并使用它
  • 为 vimeo 开发者创建应用a link
  • 使用您的应用访问令牌和视频 ID,您可以获得视频网址,然后将其传递给 Exo 播放器

第二个解决方案(解决方法和快速解决方案)

  • 使用网页视图重定向到 .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
    }

答案 1 :(得分:0)

您是要播放所有的Vimeo视频,还是只是上传的Vimeo视频?

我认为问题在于您要提取的mp4文件实际上无效,或者您没有使用oauth令牌(如果您不拥有它)就没有权限对其进行流传输。

您可以签出vimeo网络库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获取embed链接,然后从API中提取MP4文件链接。嵌入代码?只是一个主意。