【问题标题】:Exoplayer problem with streaming encrypted video from server从服务器流式传输加密视频的 Exoplayer 问题
【发布时间】:2019-04-15 11:55:30
【问题描述】:

我的服务器上有一个加密的视频,我想使用 exoplayer 播放该视频,但我找不到任何代码可以完全回答我的问题。我不知道如何使用 customDatasource 以及如何准确地附加它 exoplayer。

我尝试了一些来自互联网的代码示例,但它给了我无法识别的格式异常

【问题讨论】:

  • 您的视频使用哪种编码方式?是破折号,普通还是任何其他编码
  • 我不知道视频流和编码视频是由客户端加密的,他要求我在我正在开发的应用程序上解密和流式传输。他不是技术背景,所以问他这些问题是没有用的。我只知道视频是使用密码加密的。并具有 .encrypted 格式
  • 它只解释了如何从文件系统流式传输文件。我想从服务器流式传输它
  • 流媒体也很简单。您只需要提供您的服务器 url 而不是本地 url,例如: Uri uri = Uri.parse(serverUrl); .现在使用这个 uri 来构建你的数据源

标签: android encryption video-streaming exoplayer2.x


【解决方案1】:

最近我在我的项目中实现了 exoplayer。

首先创建一个片段或活动

class VideoViewFragment : Fragment() {

    var dataSourceFac: DataSource.Factory? = null

    companion object {
        var nPlayer: ExoPlayer? = null
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_video_view, container, false)
    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        getBundledArguments()
        ivCancel.setOnClickListener {
            if (nPlayer != null) {
                nPlayer!!.release()
                nPlayer = null
            }
            activity?.onBackPressed()
        }
    }


    private fun getBundledArguments() {
        if (arguments != null) {
            if (arguments?.getString(Constants.VIDEO_URL) != null)
                playVideo(arguments?.getString(Constants.VIDEO_URL)!!)
            else
                activity?.onBackPressed()
        }
    }

    private fun playVideo(videoUrl: String) {
        val player: ExoPlayer
        if (nPlayer != null) {
            nPlayer!!.release()
            nPlayer = null
        }

        val defaultBandwidthMeter = DefaultBandwidthMeter()
        val dataSourceFactory = DefaultDataSourceFactory(activity, Util.getUserAgent(context, context!!.getString(com.app.tourguide.R.string.app_name)), defaultBandwidthMeter)
        dataSourceFac = dataSourceFactory


        val videoTrackSelectionFactory = AdaptiveTrackSelection.Factory(defaultBandwidthMeter)
        val trackSelector = DefaultTrackSelector(videoTrackSelectionFactory)
        val contentMediaSource = buildMediaSource(Uri.parse(videoUrl))

        val mediaSources = arrayOfNulls<MediaSource>(2) //The Size must change depending on the Uris
        mediaSources[0] = contentMediaSource //uri
        val subtitleSource = SingleSampleMediaSource(Uri.parse("https://www.iandevlin.com/html5test/webvtt/upc-video-subtitles-en.vtt"),
                dataSourceFactory, Format.createTextSampleFormat(null, MimeTypes.TEXT_VTT, Format.NO_VALUE, "en", null),
                C.TIME_UNSET)

        // mediaSources[1] = subtitleSource

        //val mediaSource = MergingMediaSource(mediaSources[0], mediaSources[1])

        player = ExoPlayerFactory.newSimpleInstance(context, trackSelector)
        player.setPlayWhenReady(true)
        playerView.player = player

        player.prepare(contentMediaSource)
        nPlayer = player


        nPlayer?.addListener(object : Player.EventListener {
            override fun onPlaybackParametersChanged(playbackParameters: PlaybackParameters?) {
                Log.d(TAG, "" + playbackParameters)
            }

            override fun onSeekProcessed() {
                Log.d(TAG, "")
            }

            override fun onTracksChanged(trackGroups: TrackGroupArray?, trackSelections: TrackSelectionArray?) {
                Log.d(TAG, "" + trackGroups)
            }

            override fun onPlayerError(error: ExoPlaybackException?) {
                Log.d(TAG, "" + error!!.message)
            }

            override fun onLoadingChanged(isLoading: Boolean) {
                Log.d(TAG, "loading [$isLoading]")
            }

            override fun onPositionDiscontinuity(reason: Int) {
                Log.d(TAG, "" + reason)
            }

            override fun onRepeatModeChanged(repeatMode: Int) {
                Log.d(TAG, "" + repeatMode)
            }

            override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {
                Log.d(TAG, "" + shuffleModeEnabled)
            }

            override fun onTimelineChanged(timeline: Timeline?, manifest: Any?, reason: Int) {
                Log.d(TAG, "" + timeline)
            }

            override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
                Log.d(TAG, "" + getStateString(playbackState))
                if (playbackState == Player.STATE_ENDED) {
                    if (nPlayer != null) {
                        nPlayer!!.release()
                        nPlayer = null
                        activity?.onBackPressed()
                    }
                }
            }

        })

    }

    private fun getStateString(state: Int): String {
        when (state) {
            Player.STATE_BUFFERING -> return "B"
            Player.STATE_ENDED -> return "E"
            Player.STATE_IDLE -> return "I"
            Player.STATE_READY -> return "R"
            else -> return "?"
        }
    }

    private fun buildMediaSource(uri: Uri): MediaSource {
        @C.ContentType val type = Util.inferContentType(uri)
        when (type) {
            /*C.TYPE_DASH:
               return new DashMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
            C.TYPE_SS:
               return new SsMediaSource.Factory(dataSourceFactory).createMediaSource(uri);*/
            C.TYPE_HLS -> return HlsMediaSource.Factory(dataSourceFac).createMediaSource(uri)
            C.TYPE_OTHER -> return ExtractorMediaSource.Factory(dataSourceFac).createMediaSource(uri)
            else -> throw IllegalStateException("Unsupported type: $type") as Throwable
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        if (nPlayer != null) {
            nPlayer!!.release()
            nPlayer = null
        }
    }

}









<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/black">

    <com.google.android.exoplayer2.ui.PlayerView
        android:id="@+id/playerView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        app:auto_show="true"
        app:hide_on_touch="true"
        app:resize_mode="zoom"
        app:surface_type="texture_view"
        app:use_controller="true" />

    <ImageView
        android:id="@+id/ivCancel"
        android:layout_width="48dp"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_marginTop="@dimen/_5sdp"
        android:layout_marginEnd="@dimen/_5sdp"
        android:src="@android:drawable/ic_menu_close_clear_cancel" />

</RelativeLayout>

【讨论】:

  • 它正在处理普通流,但我想流式传输加密视频
  • 视频中使用了哪种加密方式?
  • 我用过AES算法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-25
  • 2011-01-14
  • 1970-01-01
  • 2013-12-26
  • 2012-10-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多