MATLAB: VideoReader error checking - matlab

I'm doing some image processing on several thousand small .avi files. A small subset of the files appear to be damaged.
One type of damage seems to be a particular frame of the video that can't be read in. I added a try-catch block for this and it works well.
Another type of damage, however, is, according to VLC, "Broken or missing AVI Index". When VideoReader attempts to open files with this type of damage it crashes Matlab completely with the error, "MATLAB has encountered an internal problem and needs to close." And details message, "Segmentation violation detected at Wed Apr ..."
So my question is, is there any way to error check/skip videos that would cause this crash?

You may use ffmpeg for checking the integrity of video file.
See: How can I check the integrity of a video file (avi, mpeg, mp4…)?
Download static build of ffmpeg, and put ffmpeg.exe in your working directory.
Execute ffmpeg within Matlab using system command, and check the return status.
If status is not zero, the video file is corrupted.
You may also parse the output error message for finer logic.
Here is a code sample:
filename = 'input.avi';
if (isunix)
[status, cmdout] = system(['ffmpeg.exe -v error -i ', filename, ' -f null - 2']);
else
[status, cmdout] = system(['ffmpeg.exe -v error -i ', filename, ' -f null - 2>&1']);
end
if (status ~= 0)
%Dispaly cmdout if file is damaged.
disp([filename, ' is corrupted. Error: ', cmdout]);
end

Related

ffmpeg blackdetect, start_black value to mkv chapter?

I'm trying to do automatic detect chapter with blackdetect with ffmpeg.
When I use blackdetect I get result but what is the result? Its not frames? Also. Is it possible to do a script/bat-file (for windows 10, powershell or cmd) to convert the result to a "mkv xml-file" so It can be imported with mkvtoolnix?
ffmpeg -i "movie.mp4" -vf blackdetect=d=0.232:pix_th=0.1 -an -f null - 2>&1 | findstr black_duration > output.txt
result:
black_start:2457.04 black_end:2460.04 black_duration:3
black_start:3149.46 black_end:3152.88 black_duration:3.41667
black_start:3265.62 black_end:3268.83 black_duration:3.20833
black_start:3381.42 black_end:3381.92 black_duration:0.5
black_start:3386.88 black_end:3387.38 black_duration:0.5
black_start:3390.83 black_end:3391.33 black_duration:0.5
black_start:3824.29 black_end:3824.58 black_duration:0.291667
black_start:3832.71 black_end:3833.08 black_duration:0.375
black_start:3916.29 black_end:3920.29 black_duration:4
Please see the documentation on this function here. Specifically this line:
Output lines contains the time for the start, end and duration of the detected black interval expressed in seconds.
If you read further down the page you will see another function blackframe which does a similar thing but outputs the frame number rather than seconds.
If the mkvtoolnix xml file has a chapter definition facility you will be able to create a script that takes the ffmpeg output and dumps it into the correct format in any language of your choice.

Multiple file upload with mojolicious fails on large number of files

I've hit a wall and my google skills have this time failed me. I'm in the process of learning mojolicious to create a useful front end for a series of Perl scripts that I frequently use. I've got a long way through it but I'm stumped at (multiple) file uploads when the total number of files reaches 950.
Previously, I encountered the problem where- in multiple file uploads- files would begin to be uploaded, but once the filesize reached 16 mb the upload stopped. I fixed this by setting $ENV{MOJO_MAX_MESSAGE_SIZE} = 50000000000. However, this problem is different. To illustrate, this is part of my script where I try to grab the uploaded files:
my $files = $self->req->every_upload('localfiles');
for my $file ( #{$files} ) {
my $fileName = $file->filename =~ s/[^\w\d\.]+/_/gr;
$file->move_to("temporary_uploads/$fileName");
$self->app->log->debug("$fileName uploaded\n");
push #fileNames, $fileName;
};
say "FILES: ".scalar(#fileNames);
I apologise that it may be ugly. If I attempt to upload 949 files, my array #fileNames is populated correctly, but if I try to upload 950 files, my array ends up empty, and it seems as though $files is empty also. If anyone has any ideas or pointers to guide me to the solution I would be extremely grateful!
If I attempt to upload 949 files, my array #fileNames is populated correctly, but if I try to upload 950 files, my array ends up empty, and it seems as though $files is empty also.
That means the process is running out of file descriptors. In particular, the default for the Linux kernel is 1024:
For example, the kernel default for maximum number of file descriptors (ulimit -n) was 1024/1024 (soft, hard), and has been raised to 1024/4096 in Linux 2.6.39.

Suppress output to stderr in matlab

I'm trying to suppress output from a code section in a script (namely the network initialization from a Caffe network). I've tried wrapping the corresponding bit of code in an evalc command
[suppressed_output, var_output] = evalc('someFunction(input)');
But this doesn't work. I've still got loads of lines of (non-error) output from the network initialization that are clogging my logs (amidst all the wanted output printed via fprintf('') in the script). I think this happens because the corresponding function is writing to STDERR (instead of STDOUT?) - the first line it prints is this warning:
WARNING: Logging before InitGoogleLogging() is written to STDERR
... and then hundreds of lines of what it is doing follow, e.g.:
I0215 15:01:51.840272 28620 upgrade_proto.cpp:66] Attempting to upgrade input file specified using deprecated input fields: tmp-def.prototxt
I0215 15:01:51.840360 28620 upgrade_proto.cpp:69] Successfully upgraded file specified using deprecated input fields.
...
Can I somehow suppress the output to STDERR (without messing with the function content)? Ideally only locally for this specific function, since I'd still like to get potential error messages.
In case it is relevant:
I call myScript via matlab command line and its output written to a log (mlexec.log) with tee:
matlab -nodesktop -nosplash -display :1 -r "try, myScript; catch e, disp(getReport(e)), end, quit force" 2>&1| tee mlexec.log
The problem here is, that in the matlab command line call, the output from STDERR is streamed to STDOUT by this "command": 2>&1. Since the .cpp file seems to stream its output to STDERR (according to the Warning), it will be forwarded to STDOUT and eventually the log.
Streaming STDERR (2) to Nirvana with 2>NUL or a different log file (e.g. 2>mlexec.stderr.log) solves the problem.
I wanted to post this in a comment but it said I had to have 50 reputation (I have 49 now...)
I think this is what you're looking for
EDIT/UPDATE:
One thing you can do is enclose a section of your code with warning on/off statements as follows:
warning('off','all')
%your code here
warning('on','all')
This should stop any warnings being output to stderr from that section. I personally do not recommend this, it's good to know what you're doing that the MATLAB runtime does not like.

Generate delyed soundtrck - matlab

I am trying to write a function that take as input an .avi file and returned the same video but with a delayed sound track. I am using ffmpeg and I encountered a problem. this is the function:
function Delyed = Dely_Movie_Soundtrack(filename,delayed)
Wav_File_Name = strrep(filename, '.avi', '.wav'); %the output file
wav = ['ffmpeg -i',' ',filename,' ','-vn -acodec copy',' ',Wav_File_Name]; %the command
system(wav); %executes the commant
[signal, Fs] = wavread('Will.wav');
size(signal)
end
I get the following error
Data compression format (Format #85) is not supported.
I read about it on the net, but I didn't find useful (working) links.
any help would be much appreciated.
Thanks
The solution was to specificaly instruct the program to encode in a "raw" state, otherwise it just gives the name .wav, but in fact it remains mp3. This is the command:
wav = ['ffmpeg -i',' ',filename,' ','-vn -coder:a raw',' ',Wav_File_Name];
thanks

Error writing image to file in Matlab

I am trying to write an image that I do operations on to a '.tif' file in a directory. I make the results directory with Matlab using the mkdir() function.
Here is the command I am using:
[pathstr, nameWOext, ext] = fileparts(filename);
results_dir = ['results' '/results_' nameWOext];
%check to see if the directory exists already, if it doesn't make it
if(exist(results_dir) ~= 7)
mkdir(results_dir);
end
filenamezero = [nameWOext '_J' ext];
imwrite (~J, fullfile(results_dir, filenamezero)); //Error here
When Matlab gets to this line it outputs an error:
Could not open file for writing. Check directory or file permissions.
I inspected the folder 'results/results_' and the folder is read-only. Apparently mkdir() is doing this automatically.
Is there anyway to get around this?
Thanks
P.S. I am running Windows 7 using Matlab 6.1
I think your problem may be your use of the fullfile function. I think the result is that the path you are trying to pass to imwrite has a mix of \ and / for file separators.
Try using this instead:
filenamezero = [nameWOext '_J' ext];
imwrite (~J, [results_dir '/' filenamezero]);
It seems that Matlab, when using an absolute path, requires to use ' / ' instead of the ' \ '.
For example, this works for me (Windows 8.1, Matlab R2012b)
imwrite(imagename, 'C:/Users/Myworkingfolder/myimage1.jpg','jpg');
But not:
imwrite(imagename, 'C:\Users\Myworkingfolder.jpg','jpg');
And this, even if Windows itself uses the ' \ ' when you copy a path from Windows explorer.
Although, when using a relative path, such as writing in the current folder in Matlab:
imwrite(imagename, 'Myworkingfolder/myimage1.jpg','jpg');
and
imwrite(imagename, 'Myworkingfolder\myimage1.jpg','jpg');
It works out of the box. It might be with how both cases (absolute and relative paths) are implemented...