0

我正在尝试使用 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;
    }  

因此,如果有人可以帮助我解决这个问题。先感谢您。

4

1 回答 1

0

我为解决这个问题采取了完全不同的方向。我决定不单独使用 WM .Net 框架,而是使用 DirectShow.Net 框架来实现 WM Asf 读写器。这是我的问题和答案的链接。

是否可以使用 http url 作为 DirectShow .Net 中源过滤器的源位置?

于 2011-09-20T15:44:49.247 回答