0

Windows Media .Net ライブラリを使用して、asf ファイルであるオーディオ/ビデオ ファイルをコピーしようとしています。私は Windows Media フォーマット SDK に比較的慣れていないので、これを正しく行っているかどうかわかりません。ダウンロードに含まれているいくつかのサンプル プロジェクトと C++ バージョンのドキュメントを調べましたが、EndWriting を呼び出すとクラッシュする理由がわかりません。したがって、誰かがここで私が間違っていることを指摘するのを助けることができれば、感謝します.

記録を開始するためのボタンと、記録を終了するための別のボタンを持つ WinForm があります。私のクラスは IWMReaderCallback を実装し、SampleProp というプライベート クラスを使用して、OnSample メソッドで返されるポインタなどの値を保持します。そのため、OnSample メソッドでは、SampleProp インスタンスの byte[] メンバーに、返されるサンプルのコピーを入力しています。次に、SampleProp のインスタンスを、ProcessReaderSample という別のメソッドで使用されるコレクションに追加します。この別のメソッドでは、IWMReader オブジェクトと IWMWriter オブジェクトを作成しており、BeginWriting、AllocateSample、WriteSample、EndWriting を呼び出す while ループがあります。そして、それがクラッシュする場所です。これが私が使用している私のコードです...

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 Framework だけを使用するのではなく、WM Asf リーダーおよびライターを実装する DirectShow.Net Framework を使用することにしました。これが私の質問と回答へのリンクです。

DirectShow .Net でソース フィルターのソースの場所として http url を使用することは可能ですか?

于 2011-09-20T15:44:49.247 に答える