Использование SimpleExoPlayer с комнатой в качестве автономного кэша - PullRequest
0 голосов
/ 21 марта 2020

В моем проекте Android App я хочу разрешить воспроизведение видео из автономного кэша, когда пользователь не подключен к сети. По этой причине я построил приложение, используя шаблон Repository с библиотекой персистентности Room, как рекомендовано в официальных кодах Google.

Проблема в том, что когда пользователь не подключен к inte rnet, видео не воспроизводится, хотя элементы видео сохраняются в таблице базы данных Room.

Из моего Logcat вывод, я вижу следующее сообщение об ошибке:

2020-03-21 16:26:55.132 25186-25246/com.celik.abdullah.mylim6 E/ExoPlayerImplInternal: Source error.
    com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: Unable to connect to http://192.***.**.***:8000/media/Videos/2020-03-16-12-26-49-268_CzixOFI.mp4
        at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:293)
        at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:83)
        at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:938)
        at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:394)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at java.lang.Thread.run(Thread.java:762)
     Caused by: java.net.ConnectException: Connection refused
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:334)
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:196)
        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:178)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:356)
        at java.net.Socket.connect(Socket.java:586)
        at com.android.okhttp.internal.Platform.connectSocket(Platform.java:113)
        at com.android.okhttp.Connection.connectSocket(Connection.java:1455)
        at com.android.okhttp.Connection.connect(Connection.java:1413)
        at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:1700)
        at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:133)
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:466)
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:371)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:503)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:130)
        at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:561)
        at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:448)
        at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:291)

Я предполагаю, что ExoPlayer пытается установить соединение с веб-сервисом для получения видео через соответствующий URL. Итак, я думаю, что моя ExoPlayer установка как-то не так. Моя ExoPlayer настройка такова:

playerView.player = ExoPlayerFactory.newSimpleInstance(
        playerView.context,
        DefaultTrackSelector())
        .apply {
            prepare(
                ProgressiveMediaSource.Factory(DefaultHttpDataSourceFactory("exoplayer-codelab"))
                    .createMediaSource(Uri.parse(videoString)), true, false)
            playWhenReady = true
        }

videoString (к которому пытается подключиться ExoPlayer) - это URL-адрес определенного видеоэлемента, сохраненного в Room. Как я могу реорганизовать это так, чтобы ExoPlayer мог использовать кэшированное видео? Это возможно ?

Для полноты, вот класс сущности Video.kt:

@JsonClass(generateAdapter = true)
@Entity(tableName = "video_table")
data class Video(
    @PrimaryKey
    @Json(name = "id")
    val videoId: Long,
    val title: String?,
    val text:String?,
    val video: String?,    // <--- that string is hold by videoString variable u have seen above
)

Надеюсь, что кто-то может помочь.

1 Ответ

0 голосов
/ 21 марта 2020

Я не уверен, но похоже, что вы просто сохраняете URL-адрес вашего видео (хранящегося где-то в сети) в вашей базе данных. В этом случае он не будет работать без подключения к сети. В этом случае хорошим подходом будет:

1 - сохранить видео на вашем устройстве, для этого вы можете использовать эту библиотеку: https://github.com/MindorksOpenSource/PRDownloader

2 - сохранить сущность загруженного вами видео в базу данных, но используйте путь к локальному сохраненному файлу в качестве URL (видео-поля)

3 - После извлечения данных из базы данных используйте локальный путь к файлу в качестве поля videoString в этом коде фрагмент:

 .apply {
        prepare(
            ProgressiveMediaSource.Factory(DefaultHttpDataSourceFactory("exoplayer-codelab"))
                .createMediaSource(Uri.parse(videoString)), true, false)
...