我正在尝试使用 Windows Media .Net 库来复制作为 asf 文件的音频/视频文件。我对 Windows Media Format SDK 比较陌生,所以我不确定我是否做对了。我查看了下载中包含的一些示例项目并查看了 C++ 版本的文档,但我似乎无法弄清楚为什么在调用 EndWriting 时它会崩溃。因此,如果有人可以帮助指出我在这里做错了什么,我将不胜感激。
我有一个 WinForm,上面有一个按钮来开始录制,还有一个按钮来结束录制。我的类实现了 IWMReaderCallback 并使用一个名为 SampleProp 的私有类来保存指针的值,这些值将在 OnSample 方法中返回。因此,在 OnSample 方法中,我使用返回的样本副本填充 SampleProp 实例的 byte[] 成员。然后,我将 SampleProp 的实例添加到一个集合中,该集合将在另一个名为 ProcessReaderSample 的方法中使用。在这另一种方法中,我正在创建 IWMReader 和 IWMWriter 对象,并且有一个 while 循环将调用 BeginWriting、AllocateSample、WriteSample,然后是 EndWriting。这就是它崩溃的地方。这是我正在使用的代码...
public class MyClass : IWMReaderCallback
{
static readonly string _streamingFileName = "C:\\tmpStream.asf";
static readonly string _streamingURL = @"http://localhost:8080";
static readonly string _recordingFileName = "C:\\tmpRecording.asf";
IWMReader _reader = null;
IWMReaderAdvanced _readerAdvanced = null;
IWMHeaderInfo _readerHeaderInfo = null;
IWMProfile _readerProfile = null;
IWMWriter _writer = null;
IWMWriterAdvanced _writerAdvanced = null;
IWMHeaderInfo _writerHeaderInfo = null;
int _streamCount = 0;
Guid[] _guidStreamType = null;
short[] _streamNumber = null;
void GetReader()
{
WMUtils.WMCreateReader(IntPtr.Zero, Rights.Playback, out _reader);
_readerAdvanced = _reader as IWMReaderAdvanced;
_readerHeaderInfo = _reader as IWMHeaderInfo;
_reader.Open(_streamingFileName, this, IntPtr.Zero);
_readerAdvanced.SetUserProvidedClock(true);
_readerAdvanced.SetManualStreamSelection(true);
}
void GetWritter()
{
WMUtils.WMCreateWriter(IntPtr.Zero, out _writer);
_writerAdvanced = _writer as IWMWriterAdvanced;
_writerHeaderInfo = _writer as IWMHeaderInfo;
_writer.SetProfile(_readerProfile);
_writer.SetOutputFilename(_recordingFileName);
int inputCount = 0;
_writer.GetInputCount(out inputCount);
for (int i = 0; i < inputCount; i++)
{
_writer.SetInputProps(i, null);
}
}
class SampleProp
{
public int OutputNum { get; private set; }
public long SampleTime { get; private set; }
public SampleFlag Flag { get; private set; }
public byte[] Sample;
public int Size { get; private set; }
public SampleProp(int size, int outputNum, long sampleTime, SampleFlag flag)
{
Size = size;
OutputNum = outputNum;
SampleTime = sampleTime;
Flag = flag;
Sample = new byte[size];
}
}
List<SampleProp> _writableSamples = null;
public void OnSample(int dwOutputNum, long cnsSampleTime, long cnsSampleDuration, SampleFlag dwFlags, INSSBuffer pSample, IntPtr pvContext)
{
int size = 0;
pSample.GetLength(out size);
var prop = new SampleProp(size, dwOutputNum, cnsSampleTime, dwFlags);
IntPtr ptr = IntPtr.Zero;
pSample.GetBuffer(out ptr);
Marshal.Copy(ptr, prop.Sample, 0, size);
_writableSamples.Add(prop);
}
void ProcessReaderSample()
{
_event.Reset();
GetReader();
GetProfileInfo();
GetWritter();
_reader.Start(0, 0, 1.0f, IntPtr.Zero);
_isRecording = true;
var hasStarted = false;
while (_isRecording || _writableSamples.Count > 0)
{
if (_writableSamples.Count > 0)
{
_writer.BeginWriting();
INSSBuffer buffer;
_writer.AllocateSample(_writableSamples[0].Size, out buffer);
IntPtr ptr = IntPtr.Zero;
buffer.GetBuffer(out ptr);
Marshal.Copy(_writableSamples[0].Sample, 0, ptr, _writableSamples[0].Size);
buffer.SetLength(_writableSamples[0].Size);
_writer.WriteSample(_writableSamples[0].OutputNum, _writableSamples[0].SampleTime, _writableSamples[0].Flag, buffer);
Marshal.ReleaseComObject(buffer);
_writableSamples.RemoveAt(0);
_writer.EndWriting();
}
}
}
bool _isRecording = false;
public void StartRecording()
{
if (_isRecording) return;
_writableSamples = new List<SampleProp>();
Thread writingThread = new Thread(new ThreadStart(ProcessReaderSample));
writingThread.Start();
}
public void StopRecording()
{
if (!_isRecording) return;
_isRecording = false;
}
因此,如果有人可以帮助我解决这个问题。先感谢您。