//Don't forget to add reference to DirectShowLib in your project.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices.ComTypes;
using System.Runtime.InteropServices;
using DirectShowLib;
namespace graphcode
{
class Program
{
static void checkHR(int hr, string msg)
{
if (hr < 0)
{
Console.WriteLine(msg);
DsError.ThrowExceptionForHR(hr);
}
}
static void BuildGraph(IGraphBuilder pGraph, string srcFile1, string dstFile1)
{
int hr = 0;
//graph builder
ICaptureGraphBuilder2 pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
hr = pBuilder.SetFiltergraph(pGraph);
checkHR(hr, "Can't SetFiltergraph");
Guid CLSID_JRiverTimeShiftingReaderFilter = new Guid("{8303B00A-D9E3-4BD7-A79A-AD7077F54123}"); //MJTSFileReader.ax
Guid CLSID_ElecardMPEGMultiplexerx64 = new Guid("{0FD7F9F6-747D-46CF-AC0B-FA9DAE4F6299}"); //empegmux.ax
Guid CLSID_ElecardSinkfilter = new Guid("{CF2521A7-4029-4CC1-8C6E-F82BD82BB343}"); //esf.ax
//add JRiver Time-Shifting Reader Filter
IBaseFilter pJRiverTimeShiftingReaderFilter = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_JRiverTimeShiftingReaderFilter));
hr = pGraph.AddFilter(pJRiverTimeShiftingReaderFilter, "JRiver Time-Shifting Reader Filter");
checkHR(hr, "Can't add JRiver Time-Shifting Reader Filter to graph");
//set source filename
IFileSourceFilter pJRiverTimeShiftingReaderFilter_src = pJRiverTimeShiftingReaderFilter as IFileSourceFilter;
if (pJRiverTimeShiftingReaderFilter_src == null)
checkHR(unchecked((int)0x80004002), "Can't get IFileSourceFilter");
hr = pJRiverTimeShiftingReaderFilter_src.Load(srcFile1, null);
checkHR(hr, "Can't load file");
//add Elecard MPEG Multiplexer (x64)
IBaseFilter pElecardMPEGMultiplexerx64 = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_ElecardMPEGMultiplexerx64));
hr = pGraph.AddFilter(pElecardMPEGMultiplexerx64, "Elecard MPEG Multiplexer (x64)");
checkHR(hr, "Can't add Elecard MPEG Multiplexer (x64) to graph");
//connect JRiver Time-Shifting Reader Filter and Elecard MPEG Multiplexer (x64)
hr = pGraph.ConnectDirect(GetPin(pJRiverTimeShiftingReaderFilter, "Audio Output"), GetPin(pElecardMPEGMultiplexerx64, "Input #0"), null);
checkHR(hr, "Can't connect JRiver Time-Shifting Reader Filter and Elecard MPEG Multiplexer (x64)");
//connect JRiver Time-Shifting Reader Filter and Elecard MPEG Multiplexer (x64)
hr = pGraph.ConnectDirect(GetPin(pJRiverTimeShiftingReaderFilter, "Video Output"), GetPin(pElecardMPEGMultiplexerx64, "Input #1"), null);
checkHR(hr, "Can't connect JRiver Time-Shifting Reader Filter and Elecard MPEG Multiplexer (x64)");
//add Elecard Sink filter
IBaseFilter pElecardSinkfilter = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_ElecardSinkfilter));
hr = pGraph.AddFilter(pElecardSinkfilter, "Elecard Sink filter");
checkHR(hr, "Can't add Elecard Sink filter to graph");
//set destination filename
IFileSinkFilter pElecardSinkfilter_sink = pElecardSinkfilter as IFileSinkFilter;
if (pElecardSinkfilter_sink == null)
checkHR(unchecked((int)0x80004002), "Can't get IFileSinkFilter");
hr = pElecardSinkfilter_sink.SetFileName(dstFile1, null);
checkHR(hr, "Can't set filename");
//connect Elecard MPEG Multiplexer (x64) and Elecard Sink filter
hr = pGraph.ConnectDirect(GetPin(pElecardMPEGMultiplexerx64, "Output"), GetPin(pElecardSinkfilter, "Input"), null);
checkHR(hr, "Can't connect Elecard MPEG Multiplexer (x64) and Elecard Sink filter");
}
static void Main(string[] args)
{
try
{
string outfilename = args[0].Replace(".jtv", ".ts");
IGraphBuilder graph = (IGraphBuilder)new FilterGraph();
Console.WriteLine("Building graph...");
BuildGraph(graph, args[0], outfilename);
Console.WriteLine("Running...");
IMediaControl mediaControl = (IMediaControl)graph;
IMediaEvent mediaEvent = (IMediaEvent)graph;
int hr = mediaControl.Run();
checkHR(hr, "Can't run the graph");
bool stop = false;
while (!stop)
{
System.Threading.Thread.Sleep(500);
Console.Write(".");
EventCode ev;
IntPtr p1, p2;
System.Windows.Forms.Application.DoEvents();
while (mediaEvent.GetEvent(out ev, out p1, out p2, 0) == 0)
{
if (ev == EventCode.Complete || ev == EventCode.UserAbort)
{
Console.WriteLine("Done!");
stop = true;
}
else
if (ev == EventCode.ErrorAbort)
{
Console.WriteLine("An error occured: HRESULT={0:X}", p1);
mediaControl.Stop();
stop = true;
}
mediaEvent.FreeEventParams(ev, p1, p2);
}
}
}
catch (COMException ex)
{
Console.WriteLine("COM error: " + ex.ToString());
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.ToString());
}
}
static IPin GetPin(IBaseFilter filter, string pinname)
{
IEnumPins epins;
int hr = filter.EnumPins(out epins);
checkHR(hr, "Can't enumerate pins");
IntPtr fetched = Marshal.AllocCoTaskMem(4);
IPin[] pins = new IPin[1];
while (epins.Next(1, pins, fetched) == 0)
{
PinInfo pinfo;
pins[0].QueryPinInfo(out pinfo);
bool found = (pinfo.name == pinname);
DsUtils.FreePinInfo(pinfo);
if (found)
return pins[0];
}
checkHR(-1, "Pin not found");
return null;
}
}
}