Twitch with Python and ffmpeg
So the other day I tried to become a streamer. I wrote a code that does whatever it does and sends a stream of frames and sound to Twitch. Written in Python it starts FFMPEG as a subprocess and pipes bit stream to it.
It took me hours to get this configuration that perhaps someone would find useful:
key = os.environ.get("TWITCH_KEY")
soundPipe = os.environ.get("AUDIO_PIPE")
url = f"rtmp://live.twitch.tv/app/{key}"
command = [
"ffmpeg",
# "-loglevel",'-7',
"-f", "rawvideo",
"-pixel_format", "bgr24",
"-video_size", f"{WIDTH}x{HEIGHT}",
"-i", "-",
"-f", "s16le",
#"-f", "alsa",
"-ac", "2",
#"-i", "hw:1",
"-i", soundPipe,
"-ar", "44100",
"-framerate", "14",
"-c:v", "libx264",
"-preset", "fast",
"-c:a", "aac",
"-pix_fmt", "yuv420p",
"-f", "flv",
url
#'-y', 'test_video.flv'
]
# Start FFmpeg subprocess
twitchPipe = subprocess.Popen(command, stdin=subprocess.PIPE)
Things to mention:
-
loglevel
flag could reduce output of ffmpeg -
-f rawvideo -pixel_format bgr24 -video_size YYYxAAA
is a setup for ffmpeg to decode video from opencv bitstream that is piped via stdin (see-i -
flag) -
framerate 14 -c:v libx264 -preset fast -pix_fmt yuv420p -f flv
is the magic combination that turned out to be compatible with Twitch -
Setting
-preset ultrafast
resulted in no stream -
-f s16le -ac 2 -i FIFO_FILE -ar 44100 -c:a aac
is the magic string that allowed me to attach a second stream as a sound source. For that I’ve piped my sound device (hw:1
) to a named pipe withaplay
command -
Note: adding
-f alsa -i hw:1
resulted in inappropriate sound stream in my case. No idea why yet. Would have been way more straightforward -
url
is set from .env file and contains a string that is generated for each user individually and can be retrieved in the settings of your account page on Twitch -
-y testvideo.flv
is a line that could redirect your video to a local videofile for debugging purposes -
For now there seems to be a problem with
-framerate
flag since Twitch tries to stream as much frames as possible and does not want to support low framerate streams (ideally for this very stream I’d like to have about .5 frames per second). WIP looking for solution for this question