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 with aplay 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