之前在VC知识库上下载了一个基于Directshow做的音乐播放器,带歌词显示功能,觉得挺酷的。我下载了代码,编译了工程之后,运行起来的界面效果如下:
这个播放器支持的功能有:
支持播放MP3/AAC/WAV等常见的音频格式;
音乐播放控制(播放、暂停、停止、跳跃播放);
调节音量;
音乐播放过程中同步显示歌词;
歌词的文字颜色和背景色可调,并且可设置滚动方向;
歌词显示支持淡入淡出;
因为播放引擎是Directshow,这个播放器支持的音频格式挺广泛的,只要你系统上装了某种格式的解码器,都能解码对应格式的音频。播放音乐的操作封装为一个类来处理,这个类是CDXGraph,类声明如下:
class CDXGraph
{
private:
IGraphBuilder * mGraph;
IMediaControl * mMediaControl;
IMediaEventEx * mEvent;
IBasicVideo * mBasicVideo;
IBasicAudio * mBasicAudio;
IVideoWindow * mVideoWindow;
IMediaSeeking * mSeeking;
DWORD mObjectTableEntry;
public:
CDXGraph();
virtual ~CDXGraph();
public:
virtual bool Create(void);
virtual void Release(void);
virtual bool Attach(IGraphBuilder * inGraphBuilder);
IGraphBuilder * GetGraph(void); // Not outstanding reference count
IMediaEventEx * GetEventHandle(void);
bool ConnectFilters(IPin * inOutputPin, IPin * inInputPin, const AM_MEDIA_TYPE * inMediaType = 0);
void DisconnectFilters(IPin * inOutputPin);
//bool SetDisplayWindow(HWND inWindow);
bool SetNotifyWindow(HWND inWindow);
//bool ResizeVideoWindow(long inLeft, long inTop, long inWidth, long inHeight);
void HandleEvent(WPARAM inWParam, LPARAM inLParam);
bool Run(void); // Control filter graph
bool Stop(void);
bool Pause(void);
bool IsRunning(void); // Filter graph status
bool IsStopped(void);
bool IsPaused(void);
//bool SetFullScreen(BOOL inEnabled);
//bool GetFullScreen(void);
// IMediaSeeking
bool GetCurrentPosition(LONGLONG * outPosition); //获得当前播放时间(单位为100纳秒, 等于10^(-4) ms )
bool GetStopPosition(LONGLONG * outPosition);
bool SetCurrentPosition(LONGLONG inPosition); //设置当前播放时间(单位为100纳秒, 等于10^(-4) ms )
bool SetStartStopPosition(LONGLONG inStart, LONGLONG inStop);
bool GetDuration(LONGLONG * outDuration); //获得文件时间长度(单位为100纳秒, 等于10^(-4) ms )
bool SetPlaybackRate(double inRate); //设置播放速度
// Attention: range from -10000 to 0, and 0 is FULL_VOLUME.
bool SetAudioVolume(long inVolume);//调节音量
long GetAudioVolume(void);
// Attention: range from -10000(left) to 10000(right), and 0 is both.
bool SetAudioBalance(long inBalance);
long GetAudioBalance(void);
bool RenderFile(const char * inFile);
private:
void AddToObjectTable(void) ;
void RemoveFromObjectTable(void);
bool QueryInterfaces(void);
};
在分析歌词显示的代码之前,有必要介绍一下LRC歌词文件的语法和规则:
LRC 歌词是一种包含着“[*:*]”形式的“标签(tag)”的、基于纯文本的歌词专用格式。最早由郭祥祥先生(Djohan)提出并在其程序中得到应用。这种歌词文件既可以用来实现卡拉OK功能(需要专门程序),又能以普通的文字处理软件查看、编辑。当然,实际操作时通常是用专门的