Exoplayer проблема с потоковой передачей зашифрованного видео с сервера

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

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


person Abhijit Howal    schedule 15.04.2019    source источник
comment
Какую кодировку вы используете для своего видео? это тире, обычная или любая другая кодировка   -  person p.mathew13    schedule 15.04.2019
comment
Я понятия не имею о потоковой передаче и кодировании видео, видео было зашифровано клиентом, и он просит меня расшифровать и передать его в приложении, которое я разрабатываю. Он не технарь, поэтому задавать ему эти вопросы бесполезно. Знаю только, что видео зашифровано паролем. И имеет формат .encrypted   -  person Abhijit Howal    schedule 15.04.2019
comment
Проверьте, относится ли это к вашей проблеме: blog.moagrius.com /android/ stackoverflow.com/questions/ 38729220/   -  person p.mathew13    schedule 15.04.2019
comment
Это только объясняет, как передать файл из файловой системы. Я хочу транслировать его с сервера   -  person Abhijit Howal    schedule 15.04.2019
comment
Потоковая передача также проста. вам просто нужно указать URL-адрес вашего сервера вместо локального URL-адреса, например: Uri uri = Uri.parse(serverUrl); . Теперь используйте этот uri для создания источника данных.   -  person p.mathew13    schedule 15.04.2019
comment
Я построил источник данных, но я смущен этим. Как именно я должен подключить его к exoplayer? И ему также нужен восходящий параметр. Что именно вверх по течению? И как я должен предоставить ему этот параметр?   -  person Abhijit Howal    schedule 15.04.2019


Ответы (1)


Недавно я внедрил экзоплеер в свой проект.

Сначала создайте фрагмент или активность

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>
person Suraj Bahadur    schedule 15.04.2019
comment
Он работает с обычными потоками, но я хочу транслировать зашифрованное видео. - person Abhijit Howal; 15.04.2019
comment
Какой метод шифрования используется в видео? - person Suraj Bahadur; 15.04.2019
comment
Я использовал алгоритм AES - person Abhijit Howal; 15.04.2019