{"id":2009,"date":"2008-09-19T20:43:38","date_gmt":"2008-09-19T23:43:38","guid":{"rendered":"http:\/\/www.hoogervorst.ca\/arthur\/?p=2009"},"modified":"2009-12-13T14:05:17","modified_gmt":"2009-12-13T18:05:17","slug":"ffmpeg","status":"publish","type":"post","link":"http:\/\/www.hoogervorst.ca\/arthur\/?p=2009","title":{"rendered":"FFMpeg"},"content":{"rendered":"<p><span class=\"dropcap\">B<\/span>etween all the ripping of my (legally) purchased DVDs and transcoding them to the proper format for my iPod I found out that most of the applications that I used have something in common (from Videora [free] to Mediacoder (open source). All these applications actually use FFMPEG under the hood: FFMPEG literally accepts many fileformats, open-sourced and runs on too many platforms (it&#8217;s highly portable, I guess). Trouble is, since it&#8217;s  part of the other multi-platform media player (MPlayer) and, particularly, thanks to the legal minefield that is called transcoding, the binaries for FFMPEG are hard to find (<a href=\"http:\/\/sourceforge.net\/project\/showfiles.php?group_id=205275&#038;package_id=248632\">well, you can&#8217;t miss it now!<\/a>) (you can also fetch the sources and compile a binary yourself: you&#8217;d probably need to get the MingW compiler\/environment).\n<\/p>\n<p>Anyway, all videoconverter applications that I found had either crappy interfaces or they came with that &#8216;build-in&#8217; Internet browser that allows the developer to push unneeded and unwanted ads to your desktop. So yeah, it shouldn&#8217;t be too hard to build your own fricking video converter. You only need to know and study FFMPEG&#8217;s commandline options after reading this (boring code after the fold).\n<\/p>\n<div class=\"reference\">\n<p><em>Update: <\/em> Slightly related: the BBC&#8217;s programming team released <a href=\"http:\/\/diracvideo.org\/node\/18\">the very first version of their Dirac Video Compression codec<\/a>.\n<\/p>\n<\/div>\n<p><!--more--><\/p>\n<p>First of all, I (naturally) wrapped the external calls in an object, which launches a thread, using the method &#8216;execThread&#8217; as the ThreadStart procedure. I also (surprisingly) discovered that FFMPEG writes  logging to the error output (instead of the expected standard output).\n<\/p>\n<p>The code should be easy to understand (kids-play, kids-play): I decided to use the (synchronous) methods of the process class (reading stream via nprocess.StandardError). You can also use the typical asynchronous calls if you&#8217;re into events: in that case you need to flip the specific Events property of the Process object.  I also added simple &#8216;parsing&#8217; for calculating the progress of FFMPEG: not quality code but that wasn&#8217;t the point of this.\n<\/p>\n<p>As additional notes:\n<\/p>\n<p>&#8211; The specific &#8216;synchXxxx&#8217; methods are the typical .Net style method invokers to the main thread.\n<\/p>\n<p>&#8211; Don&#8217;t bother asking about specific FFMPEG command-line arguments. I don&#8217;t care.\n<\/p>\n<p>&#8211; Notice that the Windows version of FFMPEG is GPL-ed: this took me by surprise (too). From the notes (in your FFMPEG directory):<\/p>\n<p class=\"quote\">\nThis binary build license is GPL, not LGPL, please read COPYING.txt\n<\/p>\n<p>Code follows:\n<\/p>\n<p><pre>\r\n        private void execthread() {\r\n            Process nprocess = new Process();\r\n            float duration = 0.00F, current = 0.00F;\r\n\r\n            nprocess.StartInfo.FileName = Path.Combine(Application.StartupPath, \"ffmpeg.exe\");\r\n            nprocess.StartInfo.Arguments = @\"-i \"\"C:\\myfile.mpg\"\" -ar 22050 -ab 32 -f flv -s 320\u00c3\u2014240 -aspect 4:3 -y somemove.flv\";\r\n            nprocess.EnableRaisingEvents = false;\r\n            nprocess.StartInfo.UseShellExecute = false;\r\n            nprocess.StartInfo.CreateNoWindow = true;\r\n            nprocess.StartInfo.RedirectStandardOutput = true;\r\n            nprocess.StartInfo.RedirectStandardError = true;\r\n            nprocess.Start();\r\n            StreamReader d = nprocess.StandardError;\r\n            do {\r\n                string s = d.ReadLine();\r\n                if (s.Contains(\"Duration: \")) {\r\n                    string stime = functions.ExtractDuration(s);\r\n                    duration = functions.TotalStringToSeconds(stime);\r\n                    synchTotal(duration.ToString());\r\n                } else {\r\n                    if (s.Contains(\"frame=\")) {\r\n                        string currents = functions.ExtractTime(s);\r\n                        current = functions.CurrentStringToSeconds(currents);\r\n                        synchCurrent(current.ToString());\r\n                        synchTextOutput(s);\r\n                    }\r\n                }\r\n            } while (!d.EndOfStream);\r\n\r\n            nprocess.WaitForExit();           \r\n            nprocess.Close();\r\n        }\r\n<\/pre><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Between all the ripping of my (legally) purchased DVDs and transcoding them to the proper format for my iPod I found out that most of the applications that I used have something in common (from Videora [free] to Mediacoder (open &hellip; <a href=\"http:\/\/www.hoogervorst.ca\/arthur\/?p=2009\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[2,4],"tags":[56,88,365,337,109],"_links":{"self":[{"href":"http:\/\/www.hoogervorst.ca\/arthur\/index.php?rest_route=\/wp\/v2\/posts\/2009"}],"collection":[{"href":"http:\/\/www.hoogervorst.ca\/arthur\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.hoogervorst.ca\/arthur\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.hoogervorst.ca\/arthur\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.hoogervorst.ca\/arthur\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2009"}],"version-history":[{"count":1,"href":"http:\/\/www.hoogervorst.ca\/arthur\/index.php?rest_route=\/wp\/v2\/posts\/2009\/revisions"}],"predecessor-version":[{"id":2010,"href":"http:\/\/www.hoogervorst.ca\/arthur\/index.php?rest_route=\/wp\/v2\/posts\/2009\/revisions\/2010"}],"wp:attachment":[{"href":"http:\/\/www.hoogervorst.ca\/arthur\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2009"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.hoogervorst.ca\/arthur\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2009"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.hoogervorst.ca\/arthur\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2009"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}