warren-bank / Android-ExoPlayer-AirPlay-Receiver

Android app to run on a set-top box and play video URLs "cast" to it with a stateless HTTP API (based on AirPlay v1).
http://webcast-reloaded.surge.sh/airplay_sender.html
GNU General Public License v2.0
154 stars 24 forks source link

ExoPlayer AirPlay Receiver

(less formally named: "ExoAirPlayer")

Android app to run on a set-top box and play video URLs "cast" to it with a stateless HTTP API (based on AirPlay v1).


Overview:

There is no UI when the app starts. It's a foreground service with a notification, which runs a web server on port 8192. The IP address of the server is given in the notification message.

When a video URL is "cast" to the server, a video player opens full-screen.

When an audio URL is "cast" to the server, the music plays in the background.. even when the screen is off.

When either audio or video media is playing and the player's window doesn't have focus (ex: listening to background audio, or by pressing the "home" button while watching a video), another notification is added to control playback or refocus the player's window.

This page is the simplest way to send signals to a running instance, though other "high level" tools exist to capture media URLs from the wild.

Audio or video files/playlists can also be started directly from the Android file system, which makes this app a very suitable replacement for a general-purpose video player.

Playlists can be generated dynamically from:

Playlists can be read explicitly from any text file with an .m3u file extension, which lists one media item path per line:

When a video file is played from the Android file system, its directory is automatically scanned for matching subtitle file(s). A match will have the same filename and any of the following extensions: srt,ttml,vtt,webvtt,ssa,ass. Nested extension(s) can optionally be used to distinguish between different languages (ex: .en-US.srt, .es-MX.vtt).


Background:

Scope:

Design:

Usage (low level):

AirPlay v1 compatible APIs:

  # network address for running instance of 'ExoPlayer AirPlay Receiver'
  airplay_ip='192.168.1.100:8192'

  # file path for test image (on sender):
  image_path='/path/to/image.jpg'

  # URL for test image:
  image_page='https://commons.wikimedia.org/wiki/File:Android_robot.svg'
  image_url='https://upload.wikimedia.org/wikipedia/commons/thumb/d/d7/Android_robot.svg/654px-Android_robot.svg.png'

  # URLs for test video:
  videos_page='https://players.akamai.com/hls/'
  video_url_1='https://multiplatform-f.akamaihd.net/i/multi/will/bunny/big_buck_bunny_,640x360_400,640x360_700,640x360_1000,950x540_1500,.f4v.csmil/master.m3u8'
  video_url_2='https://multiplatform-f.akamaihd.net/i/multi/april11/hdworld/hdworld_,512x288_450_b,640x360_700_b,768x432_1000_b,1024x576_1400_m,.mp4.csmil/master.m3u8'
  video_url_3='https://multiplatform-f.akamaihd.net/i/multi/april11/cctv/cctv_,512x288_450_b,640x360_700_b,768x432_1000_b,1024x576_1400_m,.mp4.csmil/master.m3u8'

  # URLs for test video text captions:
  captions_page='https://github.com/gpac/gpac/tree/master/tests/media/webvtt'
  caption_url_1='https://github.com/warren-bank/Android-ExoPlayer-AirPlay-Receiver/raw/v02/tests/.captions/counter.workaround-exoplayer-issue-7122.srt'
  caption_url_2='https://github.com/warren-bank/Android-ExoPlayer-AirPlay-Receiver/raw/v02/tests/.captions/counter.vtt'
  caption_url_3='https://github.com/gpac/gpac/raw/master/tests/media/webvtt/comments.vtt'

  # URLs for test video DRM:
  #   https://exoplayer.dev/drm.html
  #     widevine:  requires Android 4.4+
  #     clearkey:  requires Android 5.0+
  #     playready: requires AndroidTV
  drm_videos_page='https://github.com/google/ExoPlayer/blob/r2.14.0/demos/main/src/main/assets/media.exolist.json'
  drm_video_url_1='https://storage.googleapis.com/wvmedia/cenc/h264/tears/tears.mpd'
  drm_video_url_1_license_scheme='widevine'
  drm_video_url_1_license_server='https://proxy.uat.widevine.com/proxy?provider=widevine_test'
  drm_video_url_2='https://playready.directtaps.net/smoothstreaming/SSWSS720H264PR/SuperSpeedway_720.ism/Manifest'
  drm_video_url_2_license_scheme='playready'
  drm_video_url_2_license_server='https://playready.directtaps.net/pr/svc/rightsmanager.asmx'

  # URLs for test audio:
  audio_flac_nfo='https://archive.org/details/tntvillage_457399'
  audio_flac_url='https://archive.org/download/tntvillage_457399/Black%20Sabbath%201970-2013/Studio%20Albums/1970%20Black%20Sabbath/1970%20Black%20Sabbath%20%5B1986%20France%20NELCD%206002%20Castle%5D/Black%20Sabbath%20-%20Black%20Sabbath%20%281986%2C%20Castle%20Communications%2C%20NELCD%206002%29.flac'
  audio_m3u_page='https://archive.org/details/Mozart_Vesperae_Solennes_de_Confessore'
  audio_mp3s_m3u='https://archive.org/download/Mozart_Vesperae_Solennes_de_Confessore/Mozart%20-%20Vesper%C3%A6%20Solennes%20de%20Confessore%20%28Cooke%29.m3u'
  audio_htm_page='https://archive.org/details/tntvillage_455310'
  audio_mp3s_htm='https://archive.org/download/tntvillage_455310/S%26G/Live/1967%20-%20Live%20From%20New%20York%20City%20%40320/'

  # file paths for test media (on receiver):
  video_path='/storage/external_SD/test-media/video/file.mp4'
  subtt_path='/storage/external_SD/test-media/video/file.srt'
  audio_path='/storage/external_SD/test-media/audio/file.mp3'
  plist_path='/storage/external_SD/test-media/all audio and video files.m3u'

  # directory paths for test media (on receiver):
  video_dir_path='/storage/external_SD/test-media/video/'
  audio_dir_path='/storage/external_SD/test-media/audio/'
  recursive_path='/storage/external_SD/test-media/'

extended APIs:

Notes:

Usage (high level):

Other Tools (high level):

Credits:

Legal: