Проблема Exoplayer с потоковой передачей зашифрованного видео с сервера - PullRequest
0 голосов
/ 15 апреля 2019

У меня есть видео на моем сервере, которое зашифровано, и я хочу воспроизвести это видео с помощью exoplayer, но я не могу найти код, который полностью отвечает на мой вопрос. Я понятия не имею, как использовать customDatasource и как мне точно прикрепить его exoplayer.

Я попробовал некоторые примеры кода из интернета, но это дает мне неопознанное исключение для формата

1 Ответ

1 голос
/ 15 апреля 2019

Недавно я внедрил 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>
...