dvrms2mpgを作った
コマンドラインで、dvr-msファイルをmpgファイルに変換するツールdvrms2mpg
- http://d.hatena.ne.jp/bellbind/20070718/1184793284 と同等のことをコマンドラインで行うものです
使い方: dvrms2mpg.exe dvrms1 dvrms2 ...
$ dvrms2mpg.exe test.dvr-ms Muxer: Leadtek MPEG Muxer Muxer Audio In: Audio In Muxer Video In: Video In Muxer Out: Output Sink: Leadtek TS Writer Sink In: Input build graph Converting to test.dvr-ms.mpg Converted test.dvr-ms.mpg
ソース: dvrms2mpg.cs
using System; using System.IO; using System.Configuration; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using DirectShowLib; namespace dvrms2mpg { public class FilterManager { private Dictionary<string, IMoniker> monikers = new Dictionary<string, IMoniker>(); public FilterManager() { IFilterMapper3 filterMapper = new FilterMapper2() as IFilterMapper3; ICreateDevEnum devEnum; filterMapper.GetICreateDevEnum(out devEnum); Guid[] categories = new Guid[] { FilterCategory.BDACPCAFilters, FilterCategory.LegacyAmFilterCategory, FilterCategory.AudioCompressorCategory, FilterCategory.VideoCompressorCategory, //FilterCategory.BDASourceFiltersCategory, }; foreach (Guid category in categories) { IEnumMoniker monikers; devEnum.CreateClassEnumerator(category, out monikers, CDef.None); monikers.Reset(); IntPtr count = new IntPtr(); IMoniker[] moniker = new IMoniker[1]; while (monikers.Next(1, moniker, count) == 0) { this.monikers[GetFilterName(moniker[0])] = moniker[0]; } Marshal.ReleaseComObject(monikers); } Marshal.ReleaseComObject(devEnum); } public IBaseFilter Get(string name) { IMoniker moniker = monikers[name]; if (moniker == null) return null; return GetFilter(moniker); } private string GetFilterName(IMoniker filterMoniker) { object bagObj; Guid propertyBagId = typeof(IPropertyBag).GUID; filterMoniker.BindToStorage(null, null, ref propertyBagId, out bagObj); IPropertyBag bag = bagObj as IPropertyBag; object nameObj; bag.Read("FriendlyName", out nameObj, null); string name = nameObj as string; Marshal.ReleaseComObject(bagObj); return name; } private IBaseFilter GetFilter(IMoniker filterMoniker) { object filterObj; Guid baseFilterId = typeof(IBaseFilter).GUID; filterMoniker.BindToObject(null, null, ref baseFilterId, out filterObj); IBaseFilter filter = filterObj as IBaseFilter; return filter; } } public class Converter { private FilterManager filters = new FilterManager(); public void Convert(string dvrmsFileName) { if (!File.Exists(dvrmsFileName)) { Console.WriteLine(dvrmsFileName + " not found"); return; } Console.WriteLine("build graph"); string outputFileName = dvrmsFileName + ".mpg"; IGraphBuilder graph = new FilterGraph() as IGraphBuilder; IBaseFilter source; graph.AddSourceFilter(dvrmsFileName, dvrmsFileName, out source); IBaseFilter decrypt1 = filters.Get("Decrypt/Tag"); graph.AddFilter(decrypt1, "Decrypt/Tag_1"); IBaseFilter decrypt3 = filters.Get("Decrypt/Tag"); graph.AddFilter(decrypt3, "Decrypt/Tag_3"); IBaseFilter muxer = filters.Get(Config("Muxer")); graph.AddFilter(muxer, "MPEG Muxer"); IBaseFilter sink = filters.Get(Config("Sink")); (sink as IFileSinkFilter).SetFileName(outputFileName, null); graph.AddFilter(sink, "MPEG Writer"); Connect(graph, source, "DVR Out - 1", decrypt1, "In(Enc/Tag)"); Connect(graph, source, "DVR Out - 3", decrypt3, "In(Enc/Tag)"); Connect(graph, decrypt1, "Out", muxer, Config("Muxer Audio In")); Connect(graph, decrypt3, "Out", muxer, Config("Muxer Video In")); Connect(graph, muxer, Config("Muxer Out"), sink, Config("Sink In")); Console.WriteLine("Converting to " + outputFileName); (graph as IMediaControl).Run(); EventCode evCode; (graph as IMediaEvent).WaitForCompletion(-1, out evCode); Console.WriteLine("Converted " + outputFileName); } private string Config(string name) { return ConfigurationManager.AppSettings[name]; } private void Connect(IGraphBuilder graph, IBaseFilter srcFilter, string outPinName, IBaseFilter destFilter, string inPinName) { IPin sPin, dPin; srcFilter.FindPin(outPinName, out sPin); destFilter.FindPin(inPinName, out dPin); graph.ConnectDirect(sPin, dPin, null); } } class Program { static void Main(string[] args) { foreach(string key in ConfigurationManager.AppSettings) { string value = ConfigurationManager.AppSettings[key]; Console.WriteLine("{0}: {1}", key, value); } Console.WriteLine(); Converter converter = new Converter(); foreach (string dvrmsFileName in args) { try { converter.Convert(dvrmsFileName); } catch (Exception ex) { Console.WriteLine(ex); } } } } }
設定: dvrms2mpg.exe.config
<?xml version="1.0"?> <configuration> <appSettings> <add key="Muxer" value="Leadtek MPEG Muxer" /> <add key="Muxer Audio In" value="Audio In" /> <add key="Muxer Video In" value="Video In" /> <add key="Muxer Out" value="Output" /> <add key="Sink" value="Leadtek TS Writer" /> <add key="Sink In" value="Input" /> </appSettings> </configuration>
使えるMuxerやWriterは環境によって違います。
ビルド
csc.exe /r:DirectShowLib-2005.dll /platform:x86 dvrms2mpg.cs
同様にAVI圧縮dvrms2aviも作ってみたけど、うまくエンコードが動かなかった。何がまずいだろうか。