Reputation: 41
I'm new to Gstreamer. I'm making a simple pipeline to record both video and audio. The pipeline should run for a pre-determined duration, then stop properly with an EOS event.
I check my log and see the EOS is properly fired every time. However, sometime the pipeline doesn't stop and keep running forever. What is the problem?
My code:
import sys
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GObject, GLib
# Initializes Gstreamer, it's variables, paths
Gst.init(sys.argv)
GObject.threads_init()
def end_recording(_a, _b, _c, pipeline):
logger.info('Timer fired, sending EOS...')
pipeline.send_event(Gst.Event.new_eos())
return False
def handle_gstreamer_message(_bus: Gst.Bus, message: Gst.Message, loop: GObject.MainLoop):
"""Show ERROR, WARN or message during the capture."""
message_type = message.type
# GStreamer Message Types and how to parse
# https://lazka.github.io/pgi-docs/Gst-1.0/flags.html#Gst.MessageType
if message_type == Gst.MessageType.EOS:
logger.info('End of stream')
loop.quit()
elif message_type == Gst.MessageType.ERROR:
err, debug = message.parse_error()
logger.error(err)
logger.debug(debug)
loop.quit()
elif message_type == Gst.MessageType.WARNING:
err, debug = message.parse_warning()
logger.error(err)
logger.debug(debug)
return True
def capture(
output_path: str,
frame_height: int = 0,
frame_width: int = 0,
record_time_seconds: int = 0,
) -> int:
return_code = os.EX_OK
loop = None
pipeline = (
f'v4l2src'
f' ! videorate'
f' ! video/x-raw, height={frame_height}, width={frame_width}, framerate={fps}/1'
f' ! nvvidconv'
f' ! omxh264enc'
f' ! mux. '
f'pulsesrc device={audio_device}'
f' ! audio/x-raw, rate=44100, channels=2, width=32, depth=32'
f' ! queue max-size-buffers=0 max-size-time=0 max-size-bytes=0'
f' ! lamemp3enc bitrate=256'
f' ! mux. '
f'qtmux name=mux'
f' ! filesink location={output_path}'
)
logger.debug(pipeline)
try:
pipeline = Gst.parse_launch(pipeline)
bus = pipeline.get_bus()
clock = pipeline.get_pipeline_clock()
recording_end_time = clock.get_time() + record_time_seconds * 1000000000
trigger = Gst.SystemClock.new_single_shot_id(clock, recording_end_time)
Gst.Clock.id_wait_async(trigger, end_recording, pipeline)
bus.add_signal_watch()
pipeline.set_state(Gst.State.PLAYING)
loop = GObject.MainLoop()
bus.connect('message', handle_gstreamer_message, loop)
loop.run()
except GLib.Error:
logger.error(f'GLib exception occurred while capturing {output_path}', exc_info=True)
return_code = os.EX_CANTCREAT
except IOError:
logger.error(f'IO exception occurred while capturing {output_path}', exc_info=True)
return_code = os.EX_IOERR
except MemoryError:
logger.error(f'Memory exception occurred while capturing {output_path}', exc_info=True)
return_code = os.EX_CANTCREAT
finally:
if loop is not None and loop.is_running():
loop.quit()
if pipeline is not None:
pipeline.set_state(Gst.State.NULL)
if return_code == os.EX_OK:
logger.info(f'Video saved at {output_path}')
if return_code != os.EX_OK:
return return_code
return return_code
Upvotes: 0
Views: 1004
Reputation: 41
The issue seems to be from the deprecated omxh264enc
. The code was running on an NVIDIA Jetson Nano. After changing omxh264enc
to nvv4l2h264enc
, the problem went away.
Upvotes: 0