having problem with mp4mux
Lajos Okos
lajos.okos at gmail.com
Wed Apr 9 07:10:25 PDT 2014
Dear Sebastian,
If I set the faststart property to yes in Windows, the output file is
created but the size remains 0. I enclosed the python source I'm using. You
will need livestreamer to test it though. I have gstreamer 1.2.3 and python
2.7 (32 bit) on a 64 bit windows 7 computer. Plugin wise I'm using the
uridecodebin, the encodebin and the filesink came with gstreamer. My
statement is that neither the quicktime nor the iso variant of the mp4mux
generates valid files if faststart is false. (Neither under Windows nor
under Linux.) If I switch faststart to True, it is working fine in Linux
but not in Windows. If I create iso-fragmented variant, it is fine both on
Linux and windows. To set up the recording format please change line 42 and
lines 50-53 in the python source.
Best Regards,
Lajos
On Wed, Apr 9, 2014 at 8:22 AM, Sebastian Dröge
<sebastian at centricular.com>wrote:
>
> On Mo, 2014-04-07 at 14:20 +0200, Lajos Okos wrote:
> > Dear Sebastian,
> >
> > I tried to run the same python code on a linux box and I made some
> > progress. On Linux I can set the faststart property of the multiplexer in
> > the encoderbin to True. In this case the code generates a valid mp4 file,
> > with a moov atom right after the ftyp atom at the begining of the file as
> > expected. On the other hand if I set the faststart property to False I
> have
> > the same result as on windows. The mdat atom has an invalid size at byte
> > offset 32.
>
> Setting faststart to true on Windows does not help either?
>
> Can you provide your sample code to reproduce this problem, either here
> or in a bug report? Also which versions of GStreamer and the plugins are
> you using?
>
> --
> Sebastian Dröge, Centricular Ltd - http://www.centricular.com
> Expertise, Straight from the Source
>
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/gstreamer-devel/attachments/20140409/40c441b8/attachment-0001.html>
-------------- next part --------------
from __future__ import print_function
from livestreamer import Livestreamer, StreamError, PluginError, NoPluginError
import gi
gi.require_version('Gst', '1.0')
from gi.repository import GObject, Gst, Gtk,GLib,GstPbutils,GstApp
# Needed for window.get_xid(), xvimagesink.set_window_handle(), respectively:
from gi.repository import GstVideo
import datetime
GObject.threads_init()
Gst.init(None)
import sys,os
def exit(msg):
print(msg, file=sys.stderr)
sys.exit()
class LivestreamerPlayer(object):
def __init__(self):
self.fd = None
self.mainloop = GObject.MainLoop()
result=True
# Pipeline that will contain the uridecode and the encoder bins
self.pipeline=Gst.Pipeline.new("pipeline")
self.bus = self.pipeline.get_bus()
self.bus.add_signal_watch()
result=self.bus.connect("message::eos", self.on_eos)
result=self.bus.connect("message::error", self.on_error)
result=self.bus.connect("message::state-changed",self.on_state_changed)
# Lets's create the uridecode bin
self.uridecode = Gst.ElementFactory.make("uridecodebin",None)
result=self.uridecode.set_property("uri", "appsrc://")
result=self.uridecode.connect("source-setup", self.on_source_setup)
result=self.uridecode.connect("pad-added",self.on_pad_added)
# Encodebin
self.containerprofile = GstPbutils.EncodingContainerProfile.new ("mp4frag", None ,Gst.Caps.from_string("video/quicktime,variant=iso-fragmented") , None)
self.videoprofile = GstPbutils.EncodingVideoProfile.new (Gst.Caps.new_empty_simple("video/x-h264"), None, Gst.Caps.new_any(), 0)
self.audioprofile = GstPbutils.EncodingAudioProfile.new (Gst.Caps.from_string("audio/mpeg,mpegversion=(int)4"), None, Gst.Caps.new_any(), 0)
self.containerprofile.add_profile(self.videoprofile)
self.containerprofile.add_profile(self.audioprofile)
self.encode = Gst.ElementFactory.make("encodebin",None)
self.encode.set_property("profile", self.containerprofile)
mux=self.encode.get_by_name("muxer")
mux.set_property("streamable",True)
mux.set_property("fragment-duration",1000)
# mux.set_property("faststart",True)
# mux.set_property("faststart-file","c://tmp//temp.mp4")
# Record with filesink
self.rec_sink=Gst.ElementFactory.make("filesink","rec_sink")
self.rec_sink.set_property("append","FALSE")
# Testing with clockoverlay
self.overlay=Gst.ElementFactory.make("clockoverlay","overlay")
self.overlay.set_property("time-format","%Y/%m/%d %H:%M:%S")
self.overlay.set_property("text","Hello")
self.pipeline.add(self.uridecode)
self.pipeline.add(self.encode)
self.pipeline.add(self.rec_sink)
self.pipeline.add(self.overlay)
self.encode.link(self.rec_sink)
def exit(self, msg):
self.stop()
exit(msg)
def stop(self):
# Stop playback and exit mainloop
self.pipeline.set_state(Gst.State.NULL)
result=self.pipeline.get_state(Gst.CLOCK_TIME_NONE)
print("State changed to NULL with result:"+str(result))
#self.recorder.set_state(Gst.State.NULL)
self.mainloop.quit()
# Close the stream
if self.fd:
self.fd.close()
def play(self, stream):
# Attempt to open the stream
try:
self.fd = stream.open()
except StreamError as err:
self.exit("Failed to open stream: {0}".format(err))
dirs=stream.url.split("/")
rec_file="Unknown"
for dir in dirs:
if dir.find(".smil")>0:
rec_file=dir.split(".")[0]+"_"+datetime.datetime.now().strftime("%Y%m%d-%H%M%S")+".mp4"
self.rec_sink.set_property("location",rec_file)
# Start playback
result=self.pipeline.set_state(Gst.State.PLAYING)
self.mainloop.run()
def on_source_setup(self, element, source):
# When this callback is called the appsrc expects
# us to feed it more data
source.connect("need-data", self.on_source_need_data)
def on_source_need_data(self, source, length):
# Attempt to read data from the stream
# print("Need data called.")
try:
data = self.fd.read(length)
except IOError as err:
self.exit("Failed to read data from stream: {0}".format(err))
# If data is empty it's the end of stream
if not data:
print("Calling end-of-stream...")
result=source.end_of_stream()
print(str(source)+": Emit End-of-stream with result "+str(result))
return
# Convert the Python bytes into a GStreamer Buffer
# and then push it to the appsrc
buf = Gst.Buffer.new_wrapped(data)
source.emit("push-buffer", buf)
def on_eos(self, bus, msg):
# Stop playback on end of stream
self.stop()
print("Pipeline stopped after eos message!")
def on_error(self, bus, msg):
# Print error message and exit on error
error = msg.parse_error()[1]
print(str(error))
self.exit(error)
def on_state_changed(self,bus,msg):
states=msg.parse_state_changed()
if msg.src.get_name() == "pipeline" and states[1]==4: #To state is PLAYING
Gst.debug_bin_to_dot_file (msg.src, Gst.DebugGraphDetails.ALL, "playbin")
print("pipeline dot file created in "+os.getenv("GST_DEBUG_DUMP_DOT_DIR"))
def on_pad_added(self,element, pad):
caps=pad.query_caps(None)
print(caps.to_string())
if caps.to_string().find("video")>=0:
overlay_src=self.overlay.get_static_pad("src")
overlay_sink=self.overlay.get_static_pad("video_sink")
sinkpad = self.encode.emit("request-pad", caps)
# This part is without clockoverlay
result = pad.link(sinkpad)
# This part is for adding clockoverlay
# result = pad.link(overlay_sink)
# print( "uridecode linked to overlay: "+str(result))
# result = overlay_src.link(sinkpad)
# print("overlay linked to recorder: "+ str(result))
else:
sinkpad = self.encode.emit("request-pad", caps)
print ("action signal returned" + str(sinkpad))
result = pad.link(sinkpad)
print("Audio link result: "+ str(result))
def main():
if len(sys.argv) < 3:
exit("Usage: {0} <url> <quality>".format(sys.argv[0]))
# Collect arguments
url = sys.argv[1]
quality = sys.argv[2]
# Create the Livestreamer session
livestreamer = Livestreamer()
# Enable logging
livestreamer.set_loglevel("info")
livestreamer.set_logoutput(sys.stdout)
# Attempt to find a plugin for this URL
try:
plugin = livestreamer.resolve_url(url)
except NoPluginError:
exit("Livestreamer is unable to handle the URL '{0}'".format(url))
# Attempt to fetch streams
try:
streams = plugin.get_streams()
except PluginError as err:
exit("Plugin error: {0}".format(err))
if len(streams) == 0:
exit("No streams found on URL '{0}'".format(url))
# Look for specified stream
if quality not in streams:
exit("Unable to find '{0}' stream on URL '{1}'".format(quality, url))
# We found the stream
stream = streams[quality]
# Create the player and start playback
player = LivestreamerPlayer()
# Blocks until playback is done
player.play(stream)
if __name__ == "__main__":
main()
More information about the gstreamer-devel
mailing list