Skip to content

Instantly share code, notes, and snippets.

@rgov
Created August 25, 2022 02:16
Show Gist options
  • Save rgov/2401f9dc5b4ae4c5fc29a7747b60e4b1 to your computer and use it in GitHub Desktop.
Save rgov/2401f9dc5b4ae4c5fc29a7747b60e4b1 to your computer and use it in GitHub Desktop.
Save an RTSP stream as a ISO BMFF-compliant MPEG-4 file
#!/usr/bin/env python
import argparse
import os
import subprocess
import struct
parser = argparse.ArgumentParser()
parser.add_argument('--output', '-o', type=argparse.FileType('wb'))
parser.add_argument('rtsp_stream')
args = parser.parse_args()
proc = subprocess.Popen(
args=[
'ffmpeg',
'-hide_banner', '-loglevel', 'warning', '-nostats',
'-rtsp_transport', 'tcp', # https://stackoverflow.com/a/61042765
'-i', args.rtsp_stream,
'-c:v', 'copy', # copy video stream
'-an', # discard audio stream
# https://developer.mozilla.org/en-US/docs/Web/API/Media_Source_Extensions_API/Transcoding_assets_for_MSE
'-f', 'mp4',
'-movflags', 'frag_keyframe+empty_moov',
'-', # output to stdout
],
stdout=subprocess.PIPE
)
while True:
try:
box_header = proc.stdout.read(8)
if len(box_header) == 0:
break
size, type = struct.unpack('>L4s', box_header)
if size == 1:
size, = struct.unpack('>Q', proc.stdout.read(8))
if size == 0:
box = box_header + proc.stdout.read()
else:
box = box_header + proc.stdout.read(size - 8)
print(f'Read box of type {type!r} and length {size}')
if args.output:
args.output.write(box)
except KeyboardInterrupt:
proc.terminate()
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment