0

Synopsis

On my Android TV, I am playing a YouTube video. Sometimes I like to "rewind" to a specific music track in a video's timeline. I'd like to automate this with adb.

I'd like to use the adb shell command to send an instruction to my Android TV, indicating that the media playback position should be set to a specific value (in milliseconds). Using the adb logcat command, I have discovered that the below log entries are being emitted.

Question: How do I use adb shell to jump to a specific time signature in a YouTube video timeline?

ADB Logcat Output

09-06 10:45:39.807 28895 28895 I starboard_media: MediaSession state: PLAYING, position: 2393000 ms, speed: 1.000000 x, duration: 4216780 ms
09-06 10:45:39.809  2939  6629 D MediaSessionService: Media button session is changed to com.google.android.youtube.tv/starboard_media (userId=0)
09-06 10:45:39.812  3296  3296 I NewAvrcpMediaPlayerList: onAddressedPlayerChanged: token=com.google.android.youtube.tv
09-06 10:45:39.812  3296  3296 W NewAvrcpMediaPlayerList: com.google.android.youtube.tv is already the active player
09-06 10:45:39.814  4557  4557 D NowPlayingListener: updateNowPlayingNotification with controller: NowPlayingMediaController {packageName = com.google.android.youtube.tv, state = 3, metadata = Music For Efficient Work — Future Garage Playlist, Music Lab, null}
09-06 10:45:39.814  4557  4557 D NowPlayingManager: onClientChanged() called with: clearing = [false]
09-06 10:45:39.814  4557  4557 D NowPlayingListener: updateMetadata() called with: metadata description = [Music For Efficient Work — Future Garage Playlist, Music Lab, null] and now playing listener: dge@441b9b5
09-06 10:45:39.815  4334  4334 D AirPlayService: onActiveSessionsChanged: controller = com.google.android.youtube.tv
09-06 10:45:39.822  3296  3296 V NewAvrcpMediaPlayerWrapper: onPlaybackStateChanged(): com.google.android.youtube.tv : PlaybackState {state=3, position=2393000, buffered position=0, speed=1.0, updated=313779254, actions=379, custom actions=[], active item id=-1, error=null}
09-06 10:45:39.824  4334  4334 D AirPlayService: onActiveSessionsChanged : Playback state = 3
09-06 10:45:39.826  3296  3296 W NewAvrcpMediaPlayerWrapper: onPlaybackStateChanged(): com.google.android.youtube.tv tried to update with no new data
09-06 10:45:39.826  5384  5384 D BasicMediaStatusFactory: Supported media session actions: 379
09-06 10:45:39.829  3296  3296 V NewAvrcpMediaPlayerWrapper: onMetadataChanged(): com.google.android.youtube.tv : { mediaId="currsong" title="Music For Efficient Work — Future Garage Playlist" artist="Music Lab" album="" duration=4216780 trackPosition=1/1 }
09-06 10:45:39.829  5384  5384 D WargMsAppMgr: A new media session detected: com.google.android.youtube.tv
09-06 10:45:39.829  5384  5384 D WargMsAppMgr: Active app is the same session. Ignore.
09-06 10:45:39.830  3370  3425 W SSServ_MediaSessionHelper: Playback state is PlaybackState {state=3, position=2393021, buffered position=0, speed=1.0, updated=313779275, actions=379, custom actions=[], active item id=-1, error=null}.
09-06 10:45:39.834  2591  3209 D SurfaceFlinger: getDisplayConfigs hwc config w:1920 h:1080
09-06 10:45:39.835  5384  5384 D BasicMediaStatusFactory: Supported media session actions: 379
09-06 10:45:39.837  2067  2642 I hwcomposer: same layer type is change to 3 from 3 for the same layer id
09-06 10:45:39.839  3296  3296 V NewAvrcpMediaPlayerWrapper: trySendMediaUpdate(): Metadata has been updated for com.google.android.youtube.tv
09-06 10:45:39.839  3296  3296 D NewAvrcpMediaPlayerList: sendMediaUpdate
09-06 10:45:39.839  3296  3296 I NewAvrcpMediaPlayerList: sendMediaUpdate: Creating a one item queue for a player with no queue
09-06 10:45:39.839  3296  3296 D NewAvrcpTargetService: onMediaUpdated: track_changed=false state=false queue=false
09-06 10:45:39.839  3296  3296 D NewAvrcpNativeInterface: sendMediaUpdate: metadata=false playStatus=false queue=false
09-06 10:45:39.839  3296  3296 D NewAvrcpTargetJni: sendMediaUpdateNative
09-06 10:45:39.839  3296  3296 I bt_stack: [INFO:avrcp_service.cc(342)] virtual void bluetooth::avrcp::AvrcpService::SendMediaUpdate(bool, bool, bool) track_changed=0 :  play_state=0 :  queue=0
09-06 10:45:39.840  2591  2620 D SurfaceFlinger: getDisplayConfigs hwc config w:1920 h:1080
09-06 10:45:39.840  3296  3296 V NewAvrcpMediaPlayerList: onActiveSessionsChanged: number of controllers: 1
09-06 10:45:39.841  3296  3296 D NewAvrcpMediaPlayerList: onActiveSessionsChanged: controller: com.google.android.youtube.tv
09-06 10:45:39.841  3296  3296 D NewAvrcpMediaPlayerList: Already have a controller for the player: com.google.android.youtube.tv, updating instead
09-06 10:45:39.845  3296  3296 D NewAvrcpMediaPlayerWrapper: com.google.android.youtube.tv: Controller for com.google.android.youtube.tv was updated.
09-06 10:45:39.847  3296  3296 D NewAvrcpMediaPlayerList: sendMediaUpdate
09-06 10:45:39.847  3296  3296 I NewAvrcpMediaPlayerList: sendMediaUpdate: Creating a one item queue for a player with no queue
09-06 10:45:39.847  3296  3296 D NewAvrcpTargetService: onMediaUpdated: track_changed=false state=false queue=false
09-06 10:45:39.847  3296  3296 D NewAvrcpNativeInterface: sendMediaUpdate: metadata=false playStatus=false queue=false
09-06 10:45:39.847  3296  3296 D NewAvrcpTargetJni: sendMediaUpdateNative
09-06 10:45:39.847  3296  3296 I bt_stack: [INFO:avrcp_service.cc(342)] virtual void bluetooth::avrcp::AvrcpService::SendMediaUpdate(bool, bool, bool) track_changed=0 :  play_state=0 :  queue=0
09-06 10:45:39.851  4557  4557 D NowPlayingManager: onMediaDataUpdated() called with: NowPlayingData [dfz@e669f31, title=Music For Efficient Work — Future Garage Playlist, artist=Music Lab]
09-06 10:45:39.857  4557  4557 D NowPlayingManager: onMediaDataUpdated: A notification for Now Playing Card has been posted with NowPlayingData [title=Music For Efficient Work — Future Garage Playlist, artist=Music Lab]
09-06 10:45:39.858  4557  4557 D NowPlayingListener: updatePlayback() called with: state = [PlaybackState {state=3, position=2393000, buffered position=0, speed=1.0, updated=313779254, actions=379, custom actions=[], active item id=-1, error=null}] and now playing listener: dge@441b9b5

1 Answers1

1

You can't use adb commands to force the app to jump to specific time, but you should be able to emulate media button click to skip preset number of seconds forward or backward.

Checkout this answer for details: https://stackoverflow.com/a/8483797/10302746

You probably want something like:

adb shell input keyevent 21

To simulate left key, which should rewind 5 to 10 seconds back.

Lev M.
  • 6,088
  • 1
  • 10
  • 23
  • Thanks, I figured out how to do simple things like play/pause. I was hoping that based off the application logs, that I could send an intent to the YouTube app, that indicated which position I wanted it to jump to. For example, see this text from the logs: `{state=3, position=2393021, buffered position=0, speed=1.0, updated=313779275, actions=379, custom actions=[], active item id=-1, error=null}` –  Sep 06 '21 at 18:26
  • If I could figure out how to construct an intent, I think I could use `adb shell am` to send it to the YouTube app. However, I think I would need to know the name of the Activity that I want to send the intent to as well, according to this answer: https://stackoverflow.com/questions/22634446/sending-intent-to-broadcastreceiver-from-adb –  Sep 06 '21 at 18:27
  • 1
    @TrevorSullivan that log does not indicate that an intent was received. Only that a callback inside the app was triggered. To my knowledge, youtube app is not built to receive the kind of intent you want to send. But I could be wrong. You can try and decompile the APK using something like `apktool` and look at the manifest. It will tell you what kind of intents it can receive and what activities receive them. – Lev M. Sep 06 '21 at 19:51