[Bug 736924] New: iOS 8 issue mp4 recording not playable
GStreamer (bugzilla.gnome.org)
bugzilla at gnome.org
Thu Sep 18 11:15:02 PDT 2014
https://bugzilla.gnome.org/show_bug.cgi?id=736924
GStreamer | don't know | 2.x
Summary: iOS 8 issue mp4 recording not playable
Classification: Platform
Product: GStreamer
Version: 2.x
OS/Version: other
Status: UNCONFIRMED
Severity: blocker
Priority: Normal
Component: don't know
AssignedTo: gstreamer-bugs at lists.freedesktop.org
ReportedBy: michelle211 at comcast.net
QAContact: gstreamer-bugs at lists.freedesktop.org
GNOME version: ---
We are using the following code to create mp4's on IOS using Gstreamer, this
works fine on iOS 7.x and below but on IOS we cannot play partially recorded
files, or files that haven't finished recording.
this is a severe error.
We can confirm these files will not play outside IOS using vlc either.
i // pipeline def
NSString *source = [NSString stringWithFormat:@"udpsrc address=%@
port=%@ name=zeVideoRecordSource", self.host, port];
source = [source stringByAppendingString:@" ! application/x-rtp,
media=video, clock-rate=90000, encoding-name=H264, payload=96"];
//source = [source stringByAppendingString:@" ! rtpjitterbuffer"];
// this may or may not be needed
source = [source stringByAppendingString:@" ! rtph264depay ! queue"];
//source = [source stringByAppendingString:@" ! rtph264depay"];
source = [source stringByAppendingString:@" ! h264parse"];
source = [source stringByAppendingString:@" ! video/x-h264,
framerate=24/1"];
source = [source stringByAppendingString:@" ! queue name=zeQueue"];
and the processing bin code
-(NSString *) buildNewProcessingBin
{
// TODO: element cleanup in fail state?
NSString *errMsg = nil;
// create initial elements
NSString *processingBinName = [NSString
stringWithFormat:@"processing_bin_%u", _processingBinCount];
GstElement *processingBin = gst_bin_new([processingBinName
cStringUsingEncoding:NSUTF8StringEncoding]);
GstElement *muxer = gst_element_factory_make("mp4mux", NULL);
GstElement *writer = gst_element_factory_make("filesink", NULL);
if (processingBin == NULL || muxer == NULL || writer == NULL)
{
errMsg = @"Could not create at least one element in processing bin";
LOG_ERROR(GSTR,errMsg, nil);
}
// set up the file writer, creating base directory if necessary
if (errMsg == nil)
{
// formatter for storage of video file
NSString * streamName = [[DateManager sharedInstance]
recordingTimeStampAsString];
streamName = [streamName stringByAppendingFormat:@"_%@", [self
getStreamName]];
NSString *file = [streamName stringByAppendingFormat:@"_%u",
_processingBinCount];
NSString *ext = @"mp4";
NSString *fileWithExt = [file stringByAppendingPathExtension:ext];
NSString *path = [self getStreamStorageLocation];
NSString *pathWithFile = [path
stringByAppendingPathComponent:fileWithExt];
LOG_DEBUG(GSTR,@"file storage location = %@", pathWithFile);
// remove old recordings so we don't exceed our storage limit
NSUInteger maxFiles = 110;
[self removeStaleRecordingsInStreamStorageLocation:maxFiles
doRemove:YES];
// set filesink properties
NSError *dirCreateError = nil;
BOOL didCreateDirectory = NO;
BOOL isDirectory = NO;
if (![[NSFileManager defaultManager] fileExistsAtPath:path
isDirectory:&isDirectory])
{
[[NSFileManager defaultManager] createDirectoryAtPath:path
withIntermediateDirectories:NO attributes:nil error:&dirCreateError];
didCreateDirectory = YES;
}
if (dirCreateError != nil)
{
errMsg = [NSString stringWithFormat:@"Unable to create directory at
path %@", path];
LOG_ERROR(GSTR,errMsg, nil);
LOG_ERROR(GSTR,@"Directory create error: %@",
dirCreateError.description);
}
else if (!didCreateDirectory && !isDirectory)
{
errMsg = [NSString stringWithFormat:@"File already exists at
directory path %@", path];
LOG_ERROR(GSTR,errMsg, nil);
}
else
{
g_object_set(writer,
"location", [pathWithFile
cStringUsingEncoding:NSUTF8StringEncoding],
NULL);
}
}
// add and link elements in processing bin
if (errMsg == nil)
{
gst_bin_add_many(GST_BIN(processingBin), muxer, writer, NULL);
if (!gst_element_link_many(muxer, writer, NULL))
{
errMsg = @"Could not link muxing and writing elements together in
processing bin";
LOG_ERROR(GSTR,errMsg, nil);
}
}
// add a ghost pad, but first we need a template to request the muxer sink
pad
GstPadTemplate *muxSinkPadTemplate = NULL;
if (errMsg == nil)
{
muxSinkPadTemplate =
gst_element_class_get_pad_template(GST_ELEMENT_GET_CLASS(muxer), "video_%u");
if (muxSinkPadTemplate == NULL)
{
errMsg = @"Could not get muxer sink pad template in processing
bin";
LOG_ERROR(GSTR,errMsg, nil);
}
}
// now request the muxer sink pad
GstPad *lastSinkPad = NULL;
if (errMsg == nil)
{
GstPad *sinkPad = gst_element_request_pad(muxer, muxSinkPadTemplate,
NULL, NULL);
GstPad *ghostPad = gst_ghost_pad_new("sink", sinkPad);
if (sinkPad == NULL || ghostPad == NULL)
{
errMsg = @"Could not get muxer sink pad or create ghost pad in
processing bin";
LOG_ERROR(GSTR,errMsg, nil);
}
else
{
gst_element_add_pad(processingBin, ghostPad);
lastSinkPad = gst_element_get_static_pad(writer, "sink");
}
gst_object_unref(muxSinkPadTemplate);
}
// save a reference to our new processing bin, and last sink pad in the
processing bin
if (errMsg == nil)
{
if (lastSinkPad == NULL)
{
errMsg = @"Could not get last sink pad in processing bin";
LOG_ERROR(GSTR,errMsg, nil);
}
else
{
_processingElement = processingBin;
_processingElementLastSinkPad = lastSinkPad;
_processingBinCount++;
}
}
return errMsg;
}
--
Configure bugmail: https://bugzilla.gnome.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.
More information about the gstreamer-bugs
mailing list