C# directShow IAMStreamSelect切换音轨

目前切换音轨基本的是用IAMStreamSelect接口


先看看这个接口的官方介绍:

EN
此内容没有您的语言版本,但有英语版本。
开启阅读模式

IAMStreamSelect interface

The IAMStreamSelect interface selects from the available streams on a parser filter. For example, a file might contain audio streams encoded in several languages, such as English, German, and French. The application could use this interface to select which language is played.

Members

The IAMStreamSelect interface inherits from the IUnknown interface. IAMStreamSelect also has these types of members:

  • Methods

Methods

The IAMStreamSelect interface has these methods.

Method Description
Count

Retrieves the number of available streams.

Enable

Enables or disables a given stream.

Info

Retrieves information about a given stream.

从官方文档中可以看出,这个接口就是为切换音轨而生的。但是要获得这个接口,必须parser filter暴露这个接口。我用graphicsNext来查看系统在播放mvk文件时用到的filter(不同电脑可能有所不同),在利用renderFile函数的时候就会按下面这个graph创建,如下图:

C# directShow IAMStreamSelect切换音轨_第1张图片

但是查看这个graph所有filter之后,并没有发现任何一个filter实现了这个接口。后来查看其它filter发现了lav splitter source 这个filter实现了这个接口,所以用lav splitter source这个filter来拿到IAMStreamSelect这个接口,通过“CodecTweakTool”工具设置默认的filter为lav(当然你可以用代码直接手动添加)

C# directShow IAMStreamSelect切换音轨_第2张图片




设置好后我们再来看看graph,已经是我们想要的lav splitter source,现在来写代码

C# directShow IAMStreamSelect切换音轨_第3张图片


                this.graphBuilder = (IGraphBuilder)new FilterGraph();          
                // Have the graph builder construct its the appropriate graph automatically
                hr = this.graphBuilder.RenderFile(fileName, null); //(RenderFile Methord)builds a filter graph that renders the specified file
                DsError.ThrowExceptionForHR(hr);

                IBaseFilter sourceFilter;
                graphBuilder.FindFilterByName(fileName, out sourceFilter);  //找到lav
                select = sourceFilter as IAMStreamSelect;                   //拿到IAMStreamSelect接口
                int track;
                select.Count(out track);                                    //查看流数量
                for (int i = 0; i < track; i++)
                { 
                    AMMediaType mType;
                    AMStreamSelectInfoFlags flags;
                    int id,group;
                    string name;
                    object obj, unk;

                    select.Info(i, out mType, out flags, out id, out group, out name, out obj, out unk);
                    name = name.ToUpper();
                    if (name.StartsWith("A:"))    //获取音频流
                    {
                        if (flags == AMStreamSelectInfoFlags.Exclusive)
                            curTrack = i;
                                             
                        audioTracks.Add(i);  //添加音轨
                    }
                }

然后可以利用IAMStreamSelect.enable函数切换音轨(这里只实现了包含两个音轨mvk的切换)

        public void changeVideoTrack()
        {
            try
            {
                for (int i = 0; i < audioTracks.Count; i++)
                {
                    int audioTrack = audioTracks[i];
                    if (curTrack != audioTrack)
                    {
                        
                        select.Enable(audioTrack, AMStreamSelectEnableFlags.Enable);
                        curTrack = audioTrack;
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                ZCSDiary.WriteDiary(ex.Message, diaryPath);
            }

        }



你可能感兴趣的:(学习历程)