Skip to content

Instantly share code, notes, and snippets.

@raspiduino
Last active June 9, 2026 11:56
Show Gist options
  • Select an option

  • Save raspiduino/3ea6067b5af1f9506746a4310216ba39 to your computer and use it in GitHub Desktop.

Select an option

Save raspiduino/3ea6067b5af1f9506746a4310216ba39 to your computer and use it in GitHub Desktop.
Self-stream Android camera to RTSP (or whatever ffmpeg can output) in background using scrcpy-server (you can modify for non-root)

I don't have root!

See the No Root section.

Why?

I use old Android devices as headless, remotely-controlled servers and IP cameras. I don't see anything fits my requirements of being open source, hardware-encoded, and customizable. Beside this is fun and give you total control of your flow. This is adapted from an internal project.

Currently the script is encoding H.264, but you can modify the script to stream H.265 (if your device supports it) by changing video_codec to h265 for scrcpy-server and -f h264 to -f hevc for ffmpeg.

Requirement

  • Termux (or any terminal emulator, or somehow you can run shell scripts and programs)
  • scrcpy-server.jar: you can download any scrcpy client, grab the scrcpy-server file, add .jar to its name, and put it into your phone.
  • ffmpeg. Either static linked binary or downloaded from a package manager (like Termux's pkg)
  • adb client on the phone
  • root (optional, see below)

No root

You can use any solution like enabling adb over WiFi and use an on-device adb client to connect to it. There are many guides on how to get adb on your device without root and without using another machine. Use that adb to run the app_process command. Killing the dead scrcpy-server can also be done through this local adb.

Feel free to comment below.

#!/data/data/com.termux/files/usr/bin/bash
set -e
sudo pkill -9 -f "app_process.*scrcpy" 2>/dev/null || true
adb forward --remove-all 2>/dev/null || true
sleep 1
adb forward tcp:27183 "localabstract:scrcpy_00000001"
adb forward tcp:27184 "localabstract:scrcpy_00000002"
sleep 1
# Video Server (scid=1)
su -c "CLASSPATH=/data/data/com.termux/files/usr/share/scrcpy/scrcpy-server.jar \
app_process / com.genymobile.scrcpy.Server 4.0 \
tunnel_forward=true control=false cleanup=false raw_stream=true \
video_source=camera camera_id=0 camera_size=1920x1080 \
video_codec=h264 video_codec_options=i-frame-interval=1 audio=false \
send_device_meta=false send_frame_meta=false send_stream_meta=false \
send_dummy_byte=false scid=1" &
# Audio Server (scid=2)
su -c "CLASSPATH=/data/data/com.termux/files/usr/share/scrcpy/scrcpy-server.jar \
app_process / com.genymobile.scrcpy.Server 4.0 \
tunnel_forward=true control=false cleanup=false raw_stream=true \
video=false \
audio_source=mic audio_codec=raw audio=true \
send_device_meta=false send_frame_meta=false send_stream_meta=false \
send_dummy_byte=false scid=2" &
sleep 3
# FFmpeg Muxer
exec ffmpeg \
-use_wallclock_as_timestamps 1 \
-thread_queue_size 1024 -framerate 30 -f h264 -i tcp://127.0.0.1:27183 \
-thread_queue_size 1024 -f s16le -ar 48000 -ac 1 -i tcp://127.0.0.1:27184 \
-map 0:v:0 -map 1:a:0 \
-c:v copy \
-bsf:v "setts=pts=PTS-STARTPTS:dts=DTS-STARTPTS" \
-af "aresample=async=1" \
-c:a aac -profile:a aac_low -b:a 128k \
-max_muxing_queue_size 1024 \
-rtsp_transport tcp \
-f rtsp rtsp://mediamtx_ip:8554/path
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment