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 верен.