[Closed] video metadata
Is there a way to pull video metadata from flv, mpeg, and mp4 files? Using ‘openbitmap ’ which works fine for avi and mov but not other video formats. Am trying to extract video width, height and duration.
I don’t know any way in maxscript but using .NET, you can try MediaInfo, which seems to be pretty useful according this thread:
http://stackoverflow.com/questions/9091/accessing-audio-video-metadata-with-net
Download package including the DLL here:
http://mediaarea.net/download/binary/libmediainfo0/0.7.62/MediaInfo_DLL_0.7.62_Windows_i386_WithoutInstaller.7z
For sure, there are other dlls doing that… At least it is not very long to test. It is worth giving a try!
I hope you can use .NET for your project.
A bit hacky but you can use a commandline utility called ‘ffmpeg’ to get the info from any media file… or even transcode it on the fly…
doscommand “ffmpeg -i filename.flv >> mediainfo.txt”
then load and parse the generated text file…
a bit of a detour actually but it’s a way Google around for ffmpeg and media info…
Not hacky at all! I use commandline all the time on our pipeline as I consider it to be much cleaner than having to find/deploy custom dotnet assemblies. And mostly it’s using ffmpeg or imagemagick so the exe can be run from a network location somewhere. As long as you handle the cmd dialog, (i.e using hiddendoscommand rather than doscommand) it’s just as transparent to the user.
I do use the dotnet system.diagnostics.process version as I can construct more complex argument strings and keep track of things easily. You can also process the standard output from the process directly rather than reading in the result string afterwards from a temp file. (see below)
I use FFMpeg to transcode all of our animation previews for dailies as I can embed shot and camera info as an overlay, but for something like this, I’d suggest using ffprobe.exe instead. It can also deliver the video file info in JSON format, which is a nice way of parsing the resultant data.
http://stackoverflow.com/questions/7708373/get-ffmpeg-information-in-friendly-way
-- make a structure to hold the info
struct vidOps (width,height,filename,duration,sizeMB)
vidInfo = VidOps()
-- add the path to the ffprobe executable
ffProbePath = @"C:\CMD_useful\ffprobe.exe"
theFile = @"C: emp\TestFile.mp4"
-- insert the file into the argument stream
if doesfileexist theFile then
(
args = @" -v quiet -print_format json -show_format -show_streams " + theFile
proc = dotnetobject "system.diagnostics.process"
proc.StartInfo.FileName = ffProbePath
proc.StartInfo.Arguments = args
proc.StartInfo.RedirectStandardOutput = true
-- needs UseShellExecute set to false in order to redirect IO streams
proc.StartInfo.UseShellExecute = false
proc.StartInfo.CreateNoWindow = true
proc.Start()
reader = proc.StandardOutput
while (l = reader.readline()) != undefined do
(
-- full output message
-- format "%
" l
-- or parse bits of it
parseOutLine = trimright (trimleft l "\" ") "\""
case of
(
(matchpattern parseOutLine pattern:"*filename*"):(vidInfo.filename=(filterstring parseOutLine " ,\"")[3])
(matchpattern parseOutLine pattern:"*width*"):(vidInfo.width=((filterstring parseOutLine " ,")[2]) as integer)
(matchpattern parseOutLine pattern:"*height*"):(vidInfo.height=(filterstring parseOutLine " ,")[2] as integer)
(matchpattern parseOutLine pattern:"*duration\":*"):(vidInfo.duration=((filterstring parseOutLine " ,\"")[3] as float/60))
(matchpattern parseOutLine pattern:"*size\":*"):(vidInfo.sizeMB=((filterstring parseOutLine " ,\"")[3] as float/1024./1024.))
)
)
proc.Close()
vidInfo
)
Testing out ffprobe code and seems to be right direction. The ‘@’ bits in code are giving following error: ‘at bad, expected <factor>’. Using 3dsmax9.
Nice one! That’s much cleaner then storing the cmdline output stream to a tmp textfile
the @ is a verbatim string literal, it just means it doesn’t count the backward slash as an escape charater like or
.
They were added in max 2008 so not sure why they are causing an issue without seeing your exact code. You can bypass this – try replacing \ with \ in the path and removing the @ sign.
Don’t you talk about backwards slashes (“”). Try replacing “” by “\” in paths instead.
Btw, Thanks for the usefullpiece of code, LoneRobot ;).
Oops, absolutely right, I’m in nuke python mode still. My Bad. I’ve edited my original post to avoid confusion. Thanks for spotting that.
This code is what i use for all my commandline processes – you can pretty much swap the executable and configure the argument string accordingly. Argument strings are the one thing that cause errors when using commandline, so it’s useful to be able to specify different versions for testing when transcoding video files. Especially when something like FFMpeg suffers from slightly vague and contradictory documentation.
This is a really interesting discussion guys, thanks very much. I’m a big fan of commandline stuff, so this is great to read.
Pete! Nice to see you again, as always doing some top .NETage!
Just wanted to share a cool tip, use a symlink to point to ffmpeg.exe or whatever, so that way you point all your scripts into “c:\pipeline_tools\ffmpeg” and ffmpeg will point to “c:\pipeline_tools\ffmpeg_builds\ffmpeg_build_something”, you can download and install new builds, just update the symlink and you are done, no need to change scripts and of course you can easily switch between builds if something breaks.
Managed to get code to work. Only problem now is getting it to work within folders with spaces.
– theFile = “C:\Documents and Settings\Owner\Desktop\example_video.flv”
Can’t remember exact code to do this. Also ffprobe documentation isn’t the best. How do I get total frames or fps? Duration is only giving seconds in video.
make this:
args = @" -v quiet -print_format json -show_format -show_streams " + theFile
like this:
args = @" -v quiet -print_format json -show_format -show_streams " +"\"" + theFile +"\""
Haven’t tested it but should work, it just puts quotes around the filename in the args list… something like that
double quotes: ““C:\Documents and Settings\Owner\Desktop\example_video.flv””
Can’t remember exact code to do this. Also ffprobe documentation isn’t the best. How do I get total frames or fps? Duration is only giving seconds in video.
in JSON format see “r_frame_rate”, “duration_ts” or “nb_frames”