I am troubleshooting a problem with my application that worked fine in iOS6, but when I upgraded to XCode 5 and iOS7 the AVAssetWriter quit writing video data to a file in the tmp directory. I am using AVFoundation with an AVCaptureSession to capture the video. The output file is created when the recording begins, but it is never loaded with any video data. The finishWritingWithCompletionHandler runs without any errors and calls its completion handler as expected.
Does anyone know if I need to do anything different with iOS7 that was not needed in iOS6? I have not been successful finding anything in the documentation.
Here is some more information...
Temporary file location:
/var/mobile/Applications/[App ID]/tmp/[TempFileName].MOV
Video Sample Buffer Size: 1
Audio Sample Buffer Size: 1024
Any help will be greatly appreciated.
I've had the exact same scenario, also only over iOS 7.
On my case the problem turned to be actually a corrupted video file that was captured using same app.
The problem was that after done capturing with AVAssetWriter, I was calling 'finishWriting' on background thread and accessing the media immediately, before writing was done.
Solved it using 'finishWritingWithCompletionHandler:' and accessing file only after writing done (callback from the completion handler). Remember to dispatch back to main thread because handler called from a background thread.
Hope it helps
I discovered what the problem is. First I wrongly blamed the AVAssetWriter object. It was working correctly. The actual problem came from AVPlayerItem. I was using AVPlayerItem to determine the duration of the video. No matter what I tried it always returned a duration of zero which kept my video compilation getting called. Therefore to fix the problem I instead used AVAssetItem to get the video duration and that fixed my problem. I will probably report this to Apple as a bug in the AVPlayerItem object.
avishic was right. Before iOS 7, I didn't have to include assetWriter finishWritingWithCompletionHandler, but now it will leave the file unusable if you don't.
Here is some code to illustrate:
[assetWriterInput requestMediaDataWhenReadyOnQueue:mediaInputQueue
usingBlock:
^{
CMSampleBufferRef nextBuffer;
while (assetWriterInput.readyForMoreMediaData)
{
nextBuffer = [assetReaderOutput copyNextSampleBuffer];
if (nextBuffer) {
//...
}
else {
[assetWriterInput markAsFinished];
[assetReader cancelReading];
[assetWriter finishWritingWithCompletionHandler:^{
//notify your other code that the file is ready
}];
return;
}
}
Related
The Context
I'm using the HTML video element to play HLS+Fairplay streams (VOD and live) in Safari.
My application is a Netflix-like. You can watch a video, stop, and watch another one.
Concretly, the <video> tag is created upon each play and destroyed when the player exits.
The Problem
Sometimes, after exiting the player, launching a new video causes a MEDIA_ERR_DECODE error without anymore explation.
I can trace in my code that the Fairplay certificate and the CKC have been correctly retrieved and that the media session has been created and updated (with the CKC).
In fact, when I log everything, I see the exact same logs as when it works. Except the final MEDIA_ERR_DECODE error.
When I get this error, if I immediately retry to play, the same error happens, but if I wait about 5~10 seconds, it successfully plays. It's like some resource is waiting to be garbage-collected.
What I tried
I tried playing non-DRMed videos and it works perfectly: I could play, stop, play, etc. without any issue.
So my guess is something is happening at the EME level.
I've browse the whole Internet (twice) and couldn't come up with a clear explanation.
Most of the hints I found couldn't explain my issue (e.g. bad DRM-encryption, but how could it work the first time?) or solve it (e.g. videoElement.src = "").
I'm throwing a bottle into the sea, here...
I have an unrepeatable bug of unknown origin in my single threaded window manager that occurs fairly infrequently (once every 2-3 weeks). Something happens that causes me to lose keyboard input. Mouse events are still handled properly so I know the event loop is still running, but the key press event is no longer triggered. Actually, the key is no longer grabbed. When I press XCB_MOD_MASK_4+2 to switch to desktop 2, the 2 will show up in the text editor or terminal that currently has the input focus, instead of being grabbed by the window manager. I thought maybe it was related to xcb_allow_events, so via IPC I can execute these three tests (from within the window manager, cmd is received from an external process):
if (strcmp(cmd,"test0")==0)
xcb_allow_events(wm.conn, XCB_ALLOW_ASYNC_KEYBOARD, XCB_CURRENT_TIME);
else if (strcmp(cmd,"test1")==0)
xcb_allow_events(wm.conn, XCB_ALLOW_SYNC_KEYBOARD, XCB_CURRENT_TIME);
else if (strcmp(cmd,"test2")==0)
keyboard();
void keyboard()
{
int i,m,k;
xcb_void_cookie_t cookie;
spawn("/usr/bin/xmodmap -e 'keycode 108 = Super_L'");
spawn("/usr/bin/xmodmap -e 'remove mod1 = Super_L'");
for (i=0; i<LENGTH(key_bindings); i++)
{
m = key_bindings[i].mod;
k = keysc(key_bindings[i].keysym);
info("grabbing key: %s (%d), mod: %d",key_bindings[i].keysym,k,m);
cookie = xcb_grab_key_checked(wm.conn, 0, wm.root, m, k, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
if (xcb_request_check (wm.conn, cookie))
error("can't grab key");
}
}
None of these tests help. I know the keyboard function works properly because it works on window manager startup. Also I can see in the log file that the key grabs in the keyboard function are actually being executed (without error) when prompted via IPC. The current workaround is to send sigterm to the window manager process, and then restart the wm. At that point everything works fine again.
I'm looking for techniques that might be helpful in tracking down the source of this problem, or in correcting the problem once it occurs (another test). Unfortunately, since I have no clue of the source of this problem, or what triggers it, I cannot make a simple test case to demonstrate. BTW I check the log files when this happens, and I don't see any pattern leading up to the problem. Each function logs an entry on entrance and exit.
Update 2021-02-12: I thought a restart would be a good workaround until I found the root cause of this problem. My restart function contains only one line:
execvp(lwm_argv[0], lwm_argv);
where lwm_argv is the argv provided as an argument to main.
I was very surprised to see that this did not alleviate the problem. I have to completely kill the old process then launch an new one to alleviate the problem. So this problem is PID dependant??? Further, I'm fairly convinced that this problem is somehow related to the stdout/stderr output of other applications launched from within the window manager using execvp. I've stopped launching applications from within the window manager and the problem went away. Any ideas of how launching other applications (and their output) could be affecting the keygrabs within the window manager would be appreciated.
You could try using strace or perf trace on the X server to see what it is doing with the key events. It ought to read them from somewhere in /dev/input and send them as events to connected clients.
If it isn't sending you events, then you might need to dig into its internal state, perhaps by building a debug server and connecting to it with GDB, to see why it isn't sending those events.
But if it is sending events to your WM then they're getting lost somewhere in the library stack.
I try to use datasets to get "wikipedia/20200501.en" with the code below.The progress bar shows that I just complete 11% of the total dataset, however the script quit without any output in standard outut. I checked the cached directory and find the arrow file is just not completed.
wiki = load_dataset("wikipedia", "20200501.en", split="train", download_config=download_conf)
I tried several times and got different ratio of completion but never succeed in completing the progress.Could any one help me?
env:python version:3.7
datasets version:1.1.2
MacOS
This is caused by unstable network connection. It can be solved by downloading the URL with browser or "wget" function.
I have the requirement to update an image in the App over and over again (displaying some generated data).
But after several intervals the app crashes with out of memory.
I'm updating the image with this line:
(that.detailImage.nativeElement).src = DummyImage.image1;
setting the image as base64-String. I already tried using res:// and external references and even local files. The problem stays: it keeps the memory.
Reducing the size of the image helps only to delay the crash, I even got the crash with an 1kb image, but it took some minutes.
You can find the "running" code at:
https://bitbucket.org/WarEagle/implementationproblems/src/944eedf10a14d60ec421e274760b3c2c3d9ae9a1/ImageTest/?at=master
I'm really interested in understanding what I'm doing wrong. Every solution I found so far said: "make the image smaller" but this only delays the problem.
Greetings
Torsten
p.s. don't wonder about the = undefined in the example-code, this is done because I'm setting the same image over and over again, than it works, but if I update the src-property with another image, it crashes, for this example I used = undefined to reproduce the problem without uploading thousands of images for changing them around.
I've been trying to use the log class to capture some strange device-specific failures using local storage. When I went into the Log class and traced the code I noticed what seems to be a bug.
when I call the p(String) method, it calls getWriter() to get the 'output' instance of the Writer. It will notice output is null so it calls createWriter() create it. Since I haven't set a File URL, the following code gets executed:
if(getFileURL() == null) {
return new OutputStreamWriter(Storage.getInstance().createOutputStream("CN1Log__$"));
}
On the Simulator, I notice this file is created and contains log info.
so in my app I want to display the logs after an error is detected (to debug). I call getLogContent() to retrieve it as a string but it does some strange things:
if(instance.isFileWriteEnabled()) {
if(instance.getFileURL() == null) {
instance.setFileURL("file:///" + FileSystemStorage.getInstance().getRoots()[0] + "/codenameOne.log");
}
Reader r = new InputStreamReader(FileSystemStorage.getInstance().openInputStream(instance.getFileURL()));
The main problem I see is that it's using a different file URL than the default writer location. and since the creation of the Writer didn't set the File URL, the getLogContent method will never see the logged data. (The other issue I have is a style issue that a method getting content shouldn't be setting the location for that content persistently for the instance, but that's another story).
As a workaround I think I can just call "getLogContent()" at the beginning of the application which should set the file url correctly in a place that it will retrieve it from later. I'll test that next.
In the mean time, is this a Bug, or is it functionality I don't understand from my user perspective?
It's more like "unimplemented functionality". This specific API dates back to LWUIT.
The main problem with that method is that we are currently writing into a log file and getting its contents which we might currently be in the middle of writing into can be a problem and might actually cause a failure. So this approach was mostly abandoned in favor of the more robust crash protection approach.