Android Chromecast Поиск поведения - перезапускает видео с самого начала

Я пытаюсь реализовать функцию пользовательского поиска (перемотка вперед / назад) поверх Google CastCompanionLibrary-android. Я замечаю странное поведение, когда, несмотря на то, что пользователь ищет ненулевую позицию seekBar, видео, воспроизводимое на ролике, вынуждено перезапускаться с самого начала, полностью игнорируя запрошенную позицию поиска.

Реализация прослушивателя SeekBar моего видеоплеера

 @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        int progress = seekBar.getProgress();
        if (mPlaybackState == PlaybackState.PLAYING) {
            // determine local or remote playback
            switch (mPlaybackLocation) {
                case PlaybackLocation.LOCAL:
                    mLocalVideoView.seekTo(progress);
                    break;
                case PlaybackLocation.REMOTE:
                    try {
                        mVideoCastManager.play(progress);
                    } catch (Exception e) {
                        CastUtils.handleException(mParentActivity, e);
                    }
                    break;
                default:
                    Log.d(TAG, "unknown playback location");
                    break;
            }
        } else if (mPlaybackState != PlaybackState.IDLE) {
            mLocalVideoView.seekTo(progress);
        }


    }

В отличие от этого другого связанного вопроса, я уверен, что наш потоковый сервер работает должным образом, потому что, когда я использую класс VideoCastControllerActivity по умолчанию, мы замечаем правильное поведение при поиске. Но наша цель не в том, чтобы использовать класс по умолчанию, поскольку это полноэкранный режим, и это плохо работает с нашим приложением. По сути, нам бы хотелось иметь ту же функциональность, что и в приложении Youtube, где обычная панель поиска управляет как локальным, так и удаленным проигрывателем, не покидая текущий экран в полноэкранном режиме.

Дело в том, что моя реализация очень похожа, если не идентична, приведенному ниже справочному примеру. Ключевая строка в том, что оба вызова:

mVideoCastManager.play(progress);

(И безуспешно, вызывая VideoCastManager.seekAndPlay(int position). Фактически, VideoCastControllerActivity фактически вызывает play(), которая, в свою очередь, вызывает seekAndPlay())

Ссылочный плеер (Cast-Videos) ищет реализацию

private void play(int position) {
        startControllersTimer();
        switch (mLocation) {
            case LOCAL:
                mVideoView.seekTo(position);
                mVideoView.start();
                break;
            case REMOTE:
                mPlaybackState = PlaybackState.BUFFERING;
                updatePlayButton(mPlaybackState);
                try {
                    mCastManager.play(position);
                } catch (Exception e) {
                    Utils.handleException(this, e);
                }
                break;
            default:
                break;
        }
        restartTrickplayTimer();
    }

Кстати, я замечаю, что когда строка поиска на удаленном плеере на мгновение обнаруживается, она даже не заполняет правильную позицию, которую искали, а заполняет только около 10% от всего бара. Смотрите прикрепленное изображение, где я искал 1:10 из 1:29 видео (~80%)

Это ошибка в CCL или что-то не так?

РЕДАКТИРОВАТЬ: журналы получателя и отправителя во время поиска

[565.374s] [cast.receiver.IpcChannel] Received message: {"data":"{\"requestId\":7,\"type\":\"SEEK\",\"mediaSessionId\":2,\"currentTime\":0.087,\"resumeState\":\"PLAYBACK_START\"}","namespace":"urn:x-cast:com.google.cast.media","senderId":"14:net.ajplus.beta-19"}
cast_receiver.js:40  [565.382s] [cast.receiver.CastMessageBus] Dispatching CastMessageBus message
cast_receiver.js:40  [565.397s] [cast.receiver.MediaManager] MediaManager message received
cast_receiver.js:40  [565.404s] [cast.receiver.MediaManager] Dispatching MediaManager seek event
cast_receiver.js:40  [565.409s] [cast.receiver.MediaManager] onSeek: {"requestId":7,"mediaSessionId":2,"currentTime":0.087,"resumeState":"PLAYBACK_START"}
cast_receiver.js:40  [565.420s] [cast.receiver.MediaManager] Sending broadcast status message
cast_receiver.js:40  [565.426s] [cast.receiver.IpcChannel] IPC message sent: {"namespace":"urn:x-cast:com.google.cast.media","senderId":"*:*","data":"{\"type\":\"MEDIA_STATUS\",\"status\":[{\"mediaSessionId\":2,\"playbackRate\":1,\"playerState\":\"BUFFERING\",\"currentTime\":0.087,\"supportedMediaCommands\":15,\"volume\":{\"level\":1,\"muted\":false},\"activeTrackIds\":[],\"currentItemId\":2,\"repeatMode\":\"REPEAT_OFF\"}],\"requestId\":7}"}
player.html:1 Mixed Content: The page at 'https://www.gstatic.com/eureka/player/player.html?skin' was loaded over HTTPS, but requested an insecure video 'http://bc29.domain.me/fms/2848955552001/201512/video.mp4'. This content should also be served over HTTPS.
cast_receiver.js:40  [568.490s] [cast.receiver.MediaManager] Buffering state changed, isPlayerBuffering: false old time: 0.12 current time: 1.167672
cast_receiver.js:40  [568.515s] [cast.receiver.MediaManager] Sending broadcast status message
cast_receiver.js:40  [568.538s] [cast.receiver.IpcChannel] IPC message sent: {"namespace":"urn:x-cast:com.google.cast.media","senderId":"*:*","data":"{\"type\":\"MEDIA_STATUS\",\"status\":[{\"mediaSessionId\":2,\"playbackRate\":1,\"playerState\":\"PLAYING\",\"currentTime\":1.229581,\"supportedMediaCommands\":15,\"volume\":{\"level\":1,\"muted\":false},\"activeTrackIds\":[],\"currentItemId\":2,\"repeatMode\":\"REPEAT_OFF\"}],\"requestId\":0}"}

отправитель

12-17 15:19:55.803 5639-5639/net.domain.android D/ccl_VideoCastManager: [v2.5.1] attempting to play media at position 87 seconds
12-17 15:19:55.803 5639-5639/net.domain.android D/ccl_VideoCastManager: [v2.5.1] attempting to seek media
12-17 15:19:55.902 5639-5639/net.domain.android D/ccl_VideoCastManager: [v2.5.1] RemoteMediaPlayer::onStatusUpdated() is reached
12-17 15:19:55.902 5639-5639/net.domain.android D/ccl_VideoCastManager: [v2.5.1] onRemoteMediaPlayerStatusUpdated() reached
12-17 15:19:55.902 5639-5639/net.domain.android D/ccl_VideoCastManager: [v2.5.1] onQueueUpdated() reached
12-17 15:19:55.902 5639-5639/net.domain.android D/ccl_VideoCastManager: [v2.5.1] Queue Items size: 1, Item: com.google.android.gms.cast.MediaQueueItem@f2d65998, Repeat Mode: 0, Shuffle: false
12-17 15:19:55.902 5639-5639/net.domain.android D/QueueDataProvider: Queue is updated with a list of size: 1
12-17 15:19:55.902 5639-5639/net.domain.android D/QueueDataProvider: Queue was updated
12-17 15:19:55.905 5639-5639/net.domain.android D/ccl_VideoCastManager: [v2.5.1] [queue] Queue Item is: {"media":{"contentId":"http://bc29.domain.me/fms/2848955552001/201512/video.mp4","streamType":"BUFFERED","contentType":"video\/mp4","metadata":{"metadataType":1,"images":[{"url":"http:\/\/bc29.ajmn.me\/pd\/2848955552001\/201512\/1316\/2848955552001_4663173896001_RT-60-GOPCNN-TECHNOLOGYSECURITY-151215-FINAL-SUB-thumbnail.jpg?pubId=2848955552001","width":0,"height":0},{"url":"http:\/\/api.domain.net\/pictures\/video_image\/video_Still004.jpg","width":0,"height":0}],"title":"When the GOP geeks out on surveillance technologies","subtitle":"During the fifth GOP debate, candidates went on and on how technologies could prevent the next “terrorist attack.”\r\n"},"duration":89.931},"itemId":2,"autoplay":true,"startTime":0,"preloadTime":20}
12-17 15:19:55.905 5639-5639/net.domain.android D/ccl_VideoCastManager: [v2.5.1] onRemoteMediaPlayerStatusUpdated(): Player status = buffering
12-17 15:19:55.905 5639-5639/net.domain.android D/ccl_VideoCastManager: [v2.5.1] updateMiniControllersVisibility() reached with visibility: true
12-17 15:19:55.905 5639-5639/net.domain.android D/AJPBaseActivity: onRemoteMediaPlayerStatusUpdated()
12-17 15:19:55.905 5639-5639/net.domain.android D/ccl_VideoCastNotificat: [v2.5.1] onRemoteMediaPlayerStatusUpdated() reached with status: 4
12-17 15:19:59.123 5639-5639/net.domain.android D/ccl_VideoCastManager: [v2.5.1] RemoteMediaPlayer::onStatusUpdated() is reached
12-17 15:19:59.123 5639-5639/net.domain.android D/ccl_VideoCastManager: [v2.5.1] onRemoteMediaPlayerStatusUpdated() reached
12-17 15:19:59.124 5639-5639/net.domain.android D/ccl_VideoCastManager: [v2.5.1] onQueueUpdated() reached
12-17 15:19:59.124 5639-5639/net.domain.android D/ccl_VideoCastManager: [v2.5.1] Queue Items size: 1, Item: com.google.android.gms.cast.MediaQueueItem@f2d65998, Repeat Mode: 0, Shuffle: false
12-17 15:19:59.124 5639-5639/net.domain.android D/QueueDataProvider: Queue is updated with a list of size: 1
12-17 15:19:59.124 5639-5639/net.domain.android D/QueueDataProvider: Queue was updated
12-17 15:19:59.124 5639-5639/net.domain.android D/ccl_VideoCastManager: [v2.5.1] [queue] Queue Item is: {"media":{"contentId":"http://bc29.domain.me/fms/2848955552001/201512/video.mp4","streamType":"BUFFERED","contentType":"video\/mp4","metadata":{"metadataType":1,"images":[{"url":"http://bc29.domain.me/fms/2848955552001/201512/video_thumbnail.jpg?pubId=2848955552001","width":0,"height":0},{"url":"http://bc29.domain.me/fms/2848955552001/201512/video_Still004.jpg","width":0,"height":0}],"title":"When the GOP geeks out on surveillance technologies","subtitle":"During the fifth GOP debate, candidates went on and on how technologies could prevent the next “terrorist attack.”\r\n"},"duration":89.931},"itemId":2,"autoplay":true,"startTime":0,"preloadTime":20}
12-17 15:19:59.124 5639-5639/net.domain.android D/ccl_VideoCastManager: [v2.5.1] onRemoteMediaPlayerStatusUpdated(): Player status = playing
12-17 15:19:59.125 5639-5639/net.domain.android D/ccl_BaseCastManager: [v2.5.1] startReconnectionService() for media length lef = 88700
12-17 15:19:59.127 5639-5639/net.domain.android D/ccl_VideoCastManager: [v2.5.1] startNotificationService()
12-17 15:19:59.129 5639-5639/net.domain.android D/ccl_VideoCastManager: [v2.5.1] updateMiniControllersVisibility() reached with visibility: true
12-17 15:19:59.129 5639-5639/net.domain.android D/AJPBaseActivity: onRemoteMediaPlayerStatusUpdated()
12-17 15:19:59.129 5639-5639/net.domain.android D/ccl_VideoCastNotificat: [v2.5.1] onRemoteMediaPlayerStatusUpdated() reached with status: 2
12-17 15:19:59.129 5639-5639/net.domain.android D/ccl_ReconnectionService: [v2.5.1] onStartCommand() is called
12-17 15:19:59.129 5639-5639/net.domain.android D/ccl_ReconnectionService: [v2.5.1] setUpEndTimer(): setting up a timer for the end of current media
12-17 15:19:59.139 5639-5639/net.domain.android D/ccl_VideoCastNotificat: [v2.5.1] onStartCommand
12-17 15:19:59.139 5639-5639/net.domain.android D/ccl_VideoCastNotificat: [v2.5.1] onStartCommand(): Action: ACTION_VISIBILITY false

Искать не может показать запрошенную позицию на удалённом актере

1 ответ

Решение

Время, в которое вы переходите к "play(position)", должно быть в миллисекундах, но, исходя из ваших логов, вы проходите в секундах, поэтому, если вы хотите искать 87 секунд, вам нужно передать 87000 этому методу (см. Javadoc по этому методу). Оператор журнала в CCL должен быть исправлен, чтобы отразить это (будет исправлено в следующем обновлении), но JavaDoc верен.

Другие вопросы по тегам