DirectShow技术音频播放器设计_第1页
DirectShow技术音频播放器设计_第2页
DirectShow技术音频播放器设计_第3页
DirectShow技术音频播放器设计_第4页
DirectShow技术音频播放器设计_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、泉 州 师 范 学 院毕业论文(设计)题 目 基于DirectShow的 音频播放器软件的设计 数计 学 院 计算机科学与技术 专 业 07 级 班学生姓名 黄森磊 学 号 070308046 指导教师 王荣海 职 称 讲 师 完成日期 2011年4月30 日 教务处 制26基于DirectShow的音频播放器软件的设计数学与计算机科学学院 计算机科学与技术专业 070308046黄森磊指导教师王荣海 讲师【摘要】目前多媒体软件可谓是百花齐放,争奇斗艳。他们都各持的特色,但也存在各自的缺陷。本课题的研究目的就是吸取优秀多媒体播放器软件的优秀设计,改善不良缺陷,打造一款功能完善,音频播放效果俱佳

2、的音频播放器软件。播放器的开发将采用微软最新推出的Visual Studio 2010开发。采用MFC可视化编程进行用户交互界面的开发。并且运用COM组件的编程思想,通过Microsoft DirectX SDK中的DirectShow组件命令接口进行播放器核心的开发。本设计将计划完成如下基本功能:播放控制(播放、暂停、停止、上一曲、下一曲)、播放列表、音频控制、歌词文件(MP3、WMA)播放、LRC歌词文件解析、歌词显示等多种功能。【关键词】DirectShow ;MFC;GDI+;歌词秀目 录第一章绪论11.1课题研究的目的和背景11.1.1课题研究背景11.1.2课题研究的目的11.2系

3、统主要实现内容与关键技术11.2.1实现内容11.2.2系统开发的关键技术2第二章系统分析32.1设计方案32.2可行性分析32.2.1技术可行性32.2.2经济可行性32.3功能分析3第三章系统设计与开发43.1系统功能模块设计43.1.1歌曲添加43.1.2歌曲播放控制53.1.3歌曲音量播放控制53.1.4播放器交互界面53.1.5播放列表53.1.6歌词秀53.1.7播放核心53.2系统功能实现53.2.1歌词文件解析(LRC文件解析)53.2.2桌面歌词秀秀的实现93.2.3窗体歌词秀的实现113.2.4播放核心的实现133.2.5用户界面设计133.2.6播放列表设计16第四章总结

4、23致谢23参考文献24第一章 绪论语音是人类语言的一种声学特殊表现形式,而音乐则是由有组织的乐音来表达人们思想感情、反映现实生活的一种艺术。音乐不以说教方式来传播,更多的是通过熏陶及感染的途径,潜移默化地来影响人的心灵,使更多地得到美的滋润。一款优秀的音乐播放器是享受音乐洗礼的必要条件。目前多媒体软件可谓是百花齐放,争奇斗艳。他们都各持的特色,但也存在各自的缺陷。我的课题就是“基于DirectShow的音频播放器软件的设计”,吸取优秀多媒体播放器软件的优秀设计,改善不良缺陷,打造一款功能完善,音频播放效果俱佳的音频播放器软件。播放器的开发将采用VS2010开发工具,并且利用Microsoft

5、 DirectX SDK中的DirectShow组件命令接口进行编程。1.1课题研究的目的和背景1.1.1课题研究背景音乐现在已经成为人类不可缺少的生活调剂品,也成为表达人们思想感情、反应现实生活的一种特殊艺术。音乐的高潮迭起,刚柔起伏,都是人们抒发感情,寄托感情,表现感情的艺术形式。所以音乐质量的高低影响着人们品味音乐。高质量的音乐能使人们最大程度的感受音乐所表达的感情,而低质量音乐则有可能改变人们对原有音乐的理解。所以一款优质的播放器是保证人们享受优质音乐的前提。在这网络信息化的年代,计算机已经成为生活必须品,而音乐播放器则是计算机中的常用必备软件。但是当前的音乐播放器大多功能单调,无法满

6、足人们日常生活享受音乐时所需。比如人们候享受音乐时,有时候需要结合歌词来理解感受音乐的情感;或者人们想在家里就享受KTV时K歌的乐趣,这时候准确的动态歌词秀将是不可或缺的。1.1.2课题研究的目的设计研究一款功能齐全,符合人们日常操作习惯的音乐播放器是课题研究的最终目的。本课题将克服普通音乐播放器功能单一,持续播放稳定性,无法显示歌词等缺点,使人们能使用此播放器享受音乐无穷的乐趣。1.2系统主要实现内容与关键技术1.2.1实现内容通过对DirectShow音频开发技术的相关研究,了解音频开发的原理以及过程,从而设计出一款功能完善的高质量音频播放器。这款音乐播放器实现的相关内容如下:q 简洁、美

7、观的人性化交互界面。q 播放MP3、WAV等多种格式的音频文件。q 歌曲播放控制方式实现。q 歌曲添加。q 播放列表实现。q LRC歌词文件解析q 三种形式的歌词显示方式:滚动条形式,窗口形式,桌面卡拉OK形式。1.2.2系统开发的关键技术 Visual Studio 2010 MFC开发环境Visual Studio 2010是微软公司最新推出的开发环境,是目前最流行的windows平台应用程序开发环境。Visual Studio 2010 为C+开发人员提供了极大的便利,从利用Windows 7所提供的新功能到通过使用大型基本代码提高工作效率的增强功能,每个C+开发人员都可获

8、得新的或改进的功能。MFC是微软为C+开发人员开发的一个编程框架,全称Microsoft Foundation Class Library。微软为开发人员封装了各种类,并且MFC这些类结合起来构成了一个应用程序框架,MFC为开发人员在windows下的应用程序开发提供了基础和便利。MFC框架定义了应用程序的基本框架,并提供了用户接口的标准实现方法,开发人员通过预定义的接口就可以实现自己的内容。Microsoft Visual C+还提供了相应的工具来完成这个工作:AppWizard可以用来生成初步的框架文件(代码和资源等);资源编辑器用于帮助直观地设计用户接口;ClassWizard用来协助添

9、加代码到框架文件;最后,编译,则通过类库实现了应用程序特定的逻辑。MFC实现了对应用程序概念的封装,把类、类的继承、动态约束、类的关系和相互作用等封装起来。这样封装的结果对程序员来说,是一套开发模板(或者说模式)。针对不同的应用和目的,程序员采用不同的模板。例如,SDI应用程序的模板,MDI应用程序的模板,规则DLL应用程序的模板,扩展DLL应用程序的模板,OLE/ACTIVEX应用程序的模板,等等。为了支持对应用程序概念的封装,MFC内部必须作大量的工作。例如,为了实现消息映射机制,MFC编程框架必须要保证首先得到消息,然后按既定的方法进行处理。又如,为了实现对DLL编程的支持和多线程编程的

10、支持,MFC内部使用了特别的处理方法,使用模块状态、线程状态等来管理一些重要信息。虽然,这些内部处理对程序员来说是透明的,但是,懂得和理解MFC内部机制有助于写出功能灵活而强大的程序。 Microsoft DirectShow SDKDirectShow是微软公司在ActiveMovie和Video for Windows的基础上推出的基于COM组件的流媒体处理的开发包。DirectShow为多媒体流的捕捉和回放提供了强力的支持。运用DirectShow,我们可以很方便地从WDM驱动模型的采集卡上捕获数据,并进行相应的后期处理乃至存储到文件中。DirectShow支持多种媒体格式

11、,比如Asf、Mpeg、Avi、Dv、Mp3、Wave等,为多媒体流的捕捉和回放提供了强有力的支持。DirectShow的设计初衷是简化windows平台上流媒体应用程序的开发,把程序从数据传输、硬件差别和同步机制等复杂问题中分离出来。DirectShow使用了DirectSound技术提高音频流媒体的吞吐量,高效的渲染,最终把表现流媒体数据到用户的声卡。同时,DirectShow在媒体数据中封装了时间标签从而保证其回放同步。为处理各种可能的流媒体来源、格式和硬件设备,DirectShow采用了模块化结构,在这些模块中混合、匹配这些应用,而这些模块就是所谓的“滤波器”。 COM组

12、件技术原理介绍COM component(COM组件)是微软公司为了计算机行业的软件生产更加符合人类的行为方式而开发的一种新的软件开发技术。在COM框架下,人们可以开发出各种各样的功能专一的组件,然后将它们按照需求有效组合,构成复杂的应用系统。由此带来的好处是:系统中的组件可以随时用新的组件替代,以便随时进行系统的升级和维护;可以在多个应用程序中重复利用同一个组件;可以方便的将应用程序扩展到网络环境下;COM与语言,平台无关的特性使所有的程序员均可充分发挥自己的才智与语言专长编写组件模块。COM,即组件对象模型,是关于如何建立组件以及如何通过组件建立应用系统的一个规范,说明了如何动态交替更新组

13、件。一个应用程序通常是由一个的二进制文件组成的。当编译器编译生成应用程序之后,在对下一个版本重新编译并发行新生成的版本之前,应用程序不会发生任何变化。操作系统,硬件及客户需求的改变都必须等到整个应用程序被重新编译生成。目前这种状况已经发生改变,开发人员开始将单个的应用程序分隔成单独多个独立的模块,即组件。这种做法的好处是可以随时更新出新组件代替旧组件。此时的应用程序可以随新组件不断取代旧的组件而渐趋完善。而且利用已有的组件,用户还可以快速的建立全新的应用。 第二章 系统分析2.1设计方案本课题将制作一个功能完善的音频播放器,主要实现音频播放器的播放、停止、暂停等基本操作。并设计实现播放列表功能

14、,播放列表歌曲的添加。实现lrc文件的解析,并实现歌词的三种同步显示方式。2.2可行性分析通过DirectX的DirectShow组件API函数实现播放器的播放、停止、暂停等基本操作。通过MFC实现良好的图形用户界面和播放列表、歌曲文件的添加。通过对LRC文件歌词的解析,实现歌词信息的读取和存储,并运用GDI和GDI+实现三种歌词的同步显示方式。2.2.1技术可行性播放器的开发采用Visual Studio 2010开发环境,利用DirectX中的DirectShow组件API编程接口进行程序开发。Visual Studio 2010包含了一系列高效、智能的开发工具,为程序开发人员提供了强大了

15、功能。而其中的MFC则是为可视化编程创造了便利,我们可以轻松的通过MFC进行用户交互界面的可视化开发。DirectShow则帮我们封装好了播放多媒体文件的API,我们只要通过DirectShow API就能轻松实现多种格式音频文件的播放。2.2.2经济可行性播放器的开发过程中,硬件设施投入少,开发周期短,总体成本低廉。播放器的开发采用Visual Studio 2010 的MFC开发环境并利用DirectX中DirectShow编程接口进行开发,操作简单上手,节省开发时间。综上所述,在人力、财力、物力、时间上的考虑,播放器的开发在经济上是可行的。2.3功能分析音乐播放器实现的相关内容如下:q

16、简洁、美观的人性化交互界面。q 播放MP3、WAV等多种格式的音频文件。q 歌曲播放控制方式实现。q 歌曲添加。q 播放列表实现。q LRC歌词文件解析q 三种形式的歌词显示方式:滚动条形式,窗口形式,桌面卡拉OK形式。第三章 系统设计与开发3.1系统功能模块设计在系统功能分析的基础上,生成如图3-1所示的系统功能模块图。音乐播放器歌曲添加歌曲播放控制播放列表列表歌词秀播放核心软件交互界面图3-1 系统功能模块图3.1.1歌曲添加音乐潮流在日新月异地变化着,用户对音乐的享受也在不断变化。用户经常要根据音乐潮流的变化享受不同的音乐,这时我们就需要为用户提供一个可以方便添加歌曲的功能,让用户可以方

17、便享受音乐。该功能模块就是实现用户对歌曲文件添加到播放列表,并更新播放列表的歌曲,方便用户欣赏歌曲。为方便用户添加歌曲享受歌曲的乐趣,歌曲添加模块必须要实现单个文件歌曲添加和多个歌曲文件添加功能,方便用户的各种操作需要。3.1.2歌曲播放控制播放歌曲控制,此功能模块实现对歌曲进行播放、暂停、停止、上一首、下一首、循环播放、单曲播放、随机播放等控制。我们收听音乐时,有时候听到一首美妙个音乐,这时候我们就想一直享受这首歌曲,这时我们就可以用歌曲播放控制的单曲播放了,如果觉得不喜欢了,我们可以用下一首。歌曲播放控制就是为了满足用户的各种对歌曲播放的控制,方面用户享受音乐。3.1.3歌曲音量播放控制歌

18、曲音量播放控制主要实现音量大小控制、静音控制。欣赏音乐时候,用户有时候要对不同的音乐进行声音的控制以此来增加音乐的效果,最大化的享受音乐的乐趣,所以就必须为用户提供音量大小的调节功能。当我们享受音乐时,突如其来的一个电话,我们就需要把音乐关掉,这时我们就必须为用户提供一个静音功能。3.1.4播放器交互界面用户使用软件的时候不可能自己去调用播放接口等其他操作。所以我们必须为用户提供一个良好的界面,是用户能够方便使用播放器来享受音乐,提升享受音乐的乐趣。交互界面的开发必须简洁、美观、满足用户的各种需求。为了达到用户界面的美观,将采用透明窗口,其实现原理是通过创建一个完全透明窗口,然后通过Updat

19、eLayeredWindow根据PNG背景图片的Alpha值来实现窗口的部分透明。通过对PNG图片的Alpha控制我们就可以创建各式各样的不规则窗口,这样的窗口设计方案美观又简单。3.1.5播放列表用户收听音乐如果每次都要重新添加歌曲文件,那将是多么麻烦的事情,播放列表可以帮助解决这个问题。播放列表可以保存用户想要播放的歌曲。3.1.6歌词秀歌词秀是为了配合用户享受音乐而出现的。用户可以结合歌词达到最大程度的音乐享受。播放器将实现三个歌词显示方式,满足用户的不同需求。比如桌面歌词秀,他的窗体是透明的,所以用户可以一边行其他操作一边享受歌词跟音乐带来的乐趣。3.1.7播放核心一个稳定、高效的播放

20、核心是一个优秀音乐播放必不可少的重要组成部分。3.2系统功能实现3.2.1歌词文件解析(LRC文件解析) LRC歌词文件简介LRC歌词文件是一种基于纯文本的歌词专用格式文件,包含着“*:*”形式的“标签(tag)”,最早由郭祥祥先生提出并在其程序中得到应用。LRC文件既可以用来实现卡拉OK功能,又能以普通的文字处理软件查看编辑。LRC文件包含时间标签和标识标签。标识标签一般出现在文件开头,其格式为“标识名:值”。以下是预定义的标签:ti:歌曲名称、ai:专辑名称、ar:艺人名称、by:编辑者、offset:时间补偿值。时间标签形式为mm:ss 或者mm:ss.ff。其中数字必须为

21、非负整数。时间标签可以位于某行的任意位置。一行歌词可以包含多个时间标签。根据时间标签,用户端程序就会按照顺序依次高亮显示歌词,标签也无需排序,歌词的先后顺序由程序负责。 Lyric组件结构图Lyric.dll组件CParseLyricCLyricObjectLoad()GetLyric()GetAllLyric()Parse()()ParseTag()s ()ParseLrc()s ()图3-2 Lyric组件结构图 Lyric歌词文件解析代码组件具体实现(1)CParseLyric:Parse( char* lpLyric)主要是通过CString的Find、Mi

22、d、Compare方法来实现对歌词的解析。具体代码如下所示:void CParseLyric:Parse( char* lpLyric)CString strLyric,strCurTring ;int iPos;long nLength;strLyric = lpLyric;nLength = strLyric.GetLength();iPos = strLyric.Find(L"");strCurTring = strLyric.Mid(iPos,1);while(iPos <= nLength)if (strCurTring.Compare(L"n&q

23、uot;) = 0 | strCurTring.Compare(L"r") =0)strCurTring = L" "if (strCurTring.Compare(L"") = 0)CString tagString,tagStr;while(strCurTring.Compare(L"") != 0) if (strCurTring.Compare(L"n") != 0 | strCurTring.Compare(L"r") != 0) tagStr = strCurTr

24、ing; tagString = tagString + tagStr; iPos+; strCurTring = strLyric.Mid(iPos,1);iPos+;strCurTring = strLyric.Mid(iPos,1);tagStr = ""tagString = tagString + tagStr;ParseTags(tagString); continue;elseCString strLrc,strLrc1;while(strCurTring.Compare(L"") != 0)if (strCurTring.Compare(

25、L"n") = 0 | strCurTring.Compare(L"r") =0) strCurTring = L" "strLrc1 = strCurTring;strLrc = strLrc + strLrc1; iPos+;strCurTring = strLyric.Mid(iPos,1);if (iPos >= nLength)iPos+;break;ParseLrc(strLrc);continue;(2)CParseLyric:ParseTags(CString strLyric)经过了Parse将歌词信息的标识标

26、签信息分离出来,然后再对标识标签进行单独解析。void CParseLyric:ParseTags(CString strLyric)CString strMinute, strScend;if (strLyric.Find(L"") != -1 && strLyric.Find(L":") != -1 && strLyric.Find(L"") != -1)if (strLyric.Find(L"ti") = -1 && strLyric.Find(L"a

27、l") = -1 && strLyric.Find(L"ar") = -1 &&strLyric.Find(L"by") = -1 && strLyric.Find(L"offset") = -1) strMinute = strLyric.Mid(1,2);strScend = strLyric.Mid(strLyric.Find(L":") + 1,strLyric.Find(L"") - strLyric.Find(L":

28、") - 1);m_Lyricsm_iTimeCount.nTime = (long)(_wtof(strMinute) * 60 * 1000 + (_wtof(strScend) * 1000 + m_nOffset);m_iTimeCount+;if (strLyric.Find(L"ti") != -1)m_sTitle = strLyric.Mid(strLyric.Find(L":") + 1,strLyric.Find(L"") - strLyric.Find(L":") - 1);if (

29、strLyric.Find(L"al") != -1)m_sAL = strLyric.Mid(strLyric.Find(L":") + 1,strLyric.Find(L"") - strLyric.Find(L":") - 1);if (strLyric.Find(L"ar") != -1)m_sAuthor = strLyric.Mid(strLyric.Find(L":") + 1,strLyric.Find(L"") - strLyric.Fi

30、nd(L":") - 1);if (strLyric.Find(L"by") != -1)m_sBY = strLyric.Mid(strLyric.Find(L":") + 1,strLyric.Find(L"") - strLyric.Find(L":") - 1);if (strLyric.Find(L"offset:") != -1) m_nOffset = (long)_wtof(strLyric.Mid(strLyric.Find(L":")

31、+ 1,strLyric.Find(L"") - strLyric.Find(L":") - 1);3.2.2桌面歌词秀秀的实现桌面歌词秀设计结构图DLS.dll组件CLyricWindowCLyricShowObjectLoad()SetWindow()SetWindowHideAchieveTranWnd ()ReDraw()s ()OnPlayProgresss ()图3-3桌面歌词秀结构图桌面歌词秀代码具体实现桌面歌词秀主要是为了满足用户在进行其他操作时,也能同时进行歌词的观赏而设计的。为了实现这个功能,桌面歌词秀的显

32、示窗体就必须透明的,且总要在桌面的最上层,以免被其他应用程序覆盖。所以创建桌面歌词的首要任务是要实现一个透明窗口。实现窗口透明其实就是设置窗口的属性为扩展属性WS_EX_LAYERED,这样我们就创建了一个分层窗口实现了窗口透明。以下是实现窗口透明的代码实现:void CLyricWindow:AchieveTranWnd()DWORD dwExStyle = :GetWindowLongW(m_hWnd,GWL_EXSTYLE); if(dwExStyle & WS_EX_LAYERED) != WS_EX_LAYERED) :SetWindowLong( m_hWnd , GWL_

33、EXSTYLE, dwExStyle WS_EX_LAYERED); CRect rc;:GetClientRect(:GetDesktopWindow(), &rc);/获得桌面窗口大小:SetWindowPos(m_hWnd, HWND_TOPMOST,rc.left + 300,rc.bottom - 100,800,200,SWP_NOSIZE|SWP_NOMOVE);/设置窗口为最顶层 透明窗口创建完成后,接下来将实现歌词的绘制。对于歌词的绘制,将采用GDI+来实现。因为GDI+可以实现文字从一个颜色从上到下或者从左到右渐变到另外一个颜色,这个功能可以使我们的歌词秀更加美观、

34、时尚。而且GDI+还内置了消除锯齿功能,可以使歌词显示更加清秀美观。如下是桌面歌词秀效果图:图3-3 桌面歌词秀效果图首先使用GDI+必须对其进行初始化。初始化代码实现如下:/设置使用GDI+的头文件跟静态链接库#include "gdiplus.h"#pragma comment(lib, "gdiplus.lib") using namespace Gdiplus;/初始化GDI+ /ULONG_PTR gdiplusToken;GdiplusStartupInput gdiplusStartupInput;GdiplusStartup(&g

35、diplusToken, &gdiplusStartupInput, NULL);接下来就开始进行歌词的绘制。对于歌词的绘制将采用GDI+的DrawPath方法。因为采用DrawPath实现的歌词绘制经过对比测试是最美观时尚的。文字路径绘制完成后,采用GDI+的FillPath方法来填充文字路径中的空隙。为了实现文字的颜色渐变,我们填充的画刷将采用GDI+的LinearGradientBrush。文字绘制完成后,会发现文字边缘有锯齿状,这时我们可以采用GDI+的SetSmoothingMode来消除边缘锯齿。代码具体实现方法如下:Graphics graph(memDC);/创建GDI

36、+对象GraphicsPath path;Pen pen(Color(36,62,87),1);/描边的颜色FontFamily ff(L"黑体");/创建渐变画刷Gdiplus:Color cols = Color(150,254,255),Color(0,86,175),Color(0,188,255);REAL bps=0.0f,0.5f,1.0f;LinearGradientBrush hbrush(PointF(0,0),PointF(0,85),Color:Black,Color:White);hbrush.SetInterpolationColors(cols

37、,bps,3);/消除文字锯齿graph.SetSmoothingMode(SmoothingModeAntiAlias);/消除文字锯齿/绘制文字路径path.AddString(strLrc, -1,&ff , FontStyleBold, 85, PointF(m_fLrcPos, 0.5f), NULL);graph.FillPath(&hbrush,&path);/填充文字路径graph.DrawPath(&pen, &path);桌面歌词的歌词同步,其实就是另外创建一个内存DC和Graphics 对象,然后改变画刷的颜色,再根据歌词的显示时间

38、和歌词的长度,把做为渐进的内存DC绘制到之前的内存DC中。3.2.3窗体歌词秀的实现窗体歌词秀结构图WLS.dll组件CLyricWindowCLyricShowObjectLoad()SetWindow()SetWindowHideLoad()ReDraw()s ()OnPlayProgresss ()图3-4窗体歌词秀结构图窗体歌词秀的代码具体实现图3-5 窗体歌词显示效果图窗体歌词的实现首先我们要将歌词预先显示在一个内存DC中,然后根据OnPlayProgress提供的歌曲播放进度来实现对歌词显示的渐进上行。为了实现对歌词的单句同步,另外创建一个内存D C用来

39、保存当前的正在播放的语句,根据计算将改内存DC绘制到前面创建的整体内存DC中,最后统一绘制到图形设备中。关键代码如下:HRESULT CLyricWindow:OnPlayProgress(long rtPos, long rtDur )m_rtPos = rtPos;m_rtDur = rtDur;long nStart = 0;long nEnd = 0;CComBSTR sLyric;m_spLyric->GetLyric( m_rtPos, &nStart, &nEnd, &sLyric );m_iForwardHeigt = 3; /歌词前进一次的高度为

40、3 if (nEnd - nStart != 0) m_fTime = (float)(nEnd - nStart)/10; /歌词前进一次的时间m_fNowTiem = nStart + m_fRunCount * m_fTime;/当歌曲时间超过 m_fNowTime时候则 歌词前进一次if (m_rtPos >= m_fNowTiem ) m_iTotalForHeigt = m_iTotalForHeigt + m_iForwardHeigt;m_ilrcHeight =m_iFrontHeight + m_iTotalForHeigt;m_fRunCount+;/为防止歌词前进

41、进度有误 当歌词改变时候直接讲上一次的歌词前进30if (sLyric != m_sCompareLrc)m_sCompareLrc = sLyric;m_iTotalForHeigt = 30;m_ilrcHeight =m_iFrontHeight + 30;m_fRunCount = 1;m_iTotalForHeigt = 0;m_iFrontHeight = m_iFrontHeight + 30; ReDraw( m_rtPos, nStart, nEnd, sLyric ); return S_OK;3.2.4播放核心的实现该播放器的设计核心是以DirectX中DirectSho

42、w中封装完成的接口对MP3等歌词文件进行播放。以下是代码实现。首先通过COM创建音频滤波器CComPtr<IGraphBuilder> m_spGB;HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,IID_IGraphBuilder, (void *)&m_spGB);if(FAILED(hr)return FALSE;然后通过滤波器查找播放控制接口/ Use IGraphBuilder:QueryInterface (inherited from IUnknown) /

43、 to get the IMediaControl interface.hr = m_spGB->QueryInterface(IID_IMediaControl, (void *)&m_spMC);if(FAILED(hr)return FALSE;最后我们只要获取歌曲文件路径通过m_spMC的Run()方法实现播放BOOL CPlayerManger:PlayStart(CString strFilePath)/ Create the Filter Graph Manager and query for interfaces.HRESULThr = m_spGB->Re

44、nderFile( CComBSTR(strFilePath) , NULL );if (FAILED(hr)return FALSE;hr = m_spMC->Run();return TRUE;3.2.5用户界面设计 根据需求分析用户交互界面必须实现对歌曲的播放控制、音量控制、歌词显示、程序基本的关闭、最小化等功能,并且为了美观,采用了透明窗口方式来设计界面,设计的界面效果如下图:图3-6 用户界面效果图首先设计一个透明窗口我们必须设置窗口的风格为扩展格式WS_EX_LAYERED,这样窗口就变成透明的了。代码实现如下:DWORD dwExStyle = GetWindowLong(

45、m_hWnd, GWL_EXSTYLE); if(dwExStyle & WS_EX_LAYERED) != WS_EX_LAYERED) SetWindowLong(m_hWnd, GWL_EXSTYLE, dwExStyle WS_EX_LAYERED);然后我们通过UpdateLayeredWindow实现在透明窗口上绘制背景、按钮等。CDC* pDC = GetDC();CRect rcPos;this->GetWindowRect(&rcPos);POINT ptSrc = 0, 0;POINT ptWinPos = rcPos.left,rcPos.top;S

46、IZE sizeWnd = 800,600;UpdateLayeredWindow(pDC, &ptWinPos, &sizeWnd, &m_memDC, &ptSrc, 0, &m_Blend, LWA_ALPHA); 由于窗口采用了扩展风格WS_EX_LAYERED,所以窗口中无法显示控件,所有按钮实现都是通过在内存DC中进行绘制,然后通过鼠标消息,模拟实现按钮功能。自绘按钮首先要在窗口中绘制一个按钮图片,如播放按钮绘制代码实现如下:CString strPlayImg;strPlayImg.Format(L"%simageplay.png

47、", m_szBkImgDirectory);Image* pPlayImg = new Image(strPlayImg);Graphics graph(m_memDC);graph.DrawImage(pPlayImg,rc.left + 365,rc.top + 60, 100,100);这时我们就在窗口中绘制了一个按钮,为了让按钮更加形象生动,当鼠标移动到按钮上时我们应该提示用户现,所以添加了了OnMouseMove消息,当鼠标移动到按钮区域的时候,更改按钮图片,当鼠标移出按钮区域,还原按钮图片。代码实现如下所示:void CPlayerSkin:OnMouseMove(UI

48、NT nFlags, CPoint point)Graphics graph(m_memDC);graph.SetSmoothingMode(SmoothingModeAntiAlias);/消除锯齿CRect rc;GetClientRect(&rc);CRect rcBtn;rcBtn.left = rc.left +365;rcBtn.top = rc.top + 60;rcBtn.right = rcBtn.left + 100;rcBtn.bottom = rcBtn.top + 100;if (rcBtn.PtInRect(point)CString strPlayImg;

49、strPlayImg.Format(L"%simageOnplay.png", m_szBkImgDirectory);Image* pPlayImg = new Image(strPlayImg);graph.DrawImage(pPlayImg,rc.left + 365,rc.top + 60, 100,100);elseCString strPlayImg;strPlayImg.Format(L"%simageplay.png", m_szBkImgDirectory);Image* pPlayImg = new Image(strPlayImg

50、);graph.DrawImage(pPlayImg,rc.left + 365,rc.top + 60, 100,100);当用户要对歌曲进行播放时候,就会把鼠标移动到播放按钮上,并按下鼠标左键,这时候就要实现播放。所以必须添加一个鼠标左键按下消息OnLButtonDown,来处理播放控制。代码实现如下:void CPlayerManger:OnLButtonDown(UINT nFlags, CPoint point)CRect rc;GetClientRect(&rc);CRect rcBtn;rcBtn.left = rc.left +365;rcBtn.top = rc.to

51、p + 60;rcBtn.right = rcBtn.left + 100;rcBtn.bottom = rcBtn.top + 100;if (rcBtn.PtInRect(point)if (m_bPalying = TRUE)return;m_bPalying = TRUE;PlayStart(m_sMP3);3.2.6播放列表设计播放列表设计结构图LLPlayerCPlaylistManagerCPlaylistWndDrawBKDrawItem ()DrawPlayListInfoInit() ()SavePlaylistToFiles ()图 3-7播放列表设计结构图

52、播放列表的代码具体实现(1)播放列表文件的设计播放列表信息采用xml文件保存。通过需求分析,播放列表文件需要存储歌曲的路径、歌手的信息,所以对播放列表文件设计如下图:图3-8 播放列表文件设计播放列表文件采用的是XML的保存方式,所以播放列表的创建并保存信息将采用IXMLDOMDocument、IXMLDOMElement。通过PPlaylist结构的信息,将歌曲具体信息保存到playlist.xml中。具体实现如下:BOOL CPlaylistManager:SavePlaylistToFile()CComPtr<IXMLDOMDocument> spDoc;HRE

53、SULT hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,IID_IXMLDOMDocument, (void*)&spDoc);if(!spDoc)return FALSE;CComPtr<IXMLDOMElement> spNode;spDoc->createElement(CComBSTR(L"root"), &spNode);if (!spNode)return FALSE;spDoc->appendChild(spNode, NULL);

54、for(int i=0; i<m_pPlayList.size(); i+)CComPtr<IXMLDOMElement> spPlaylistdNode; spDoc->createElement(CComBSTR(L"Playlist"), &spPlaylistdNode);spNode->appendChild(spPlaylistdNode,NULL); CString strPlayListName = L""strPlayListName = m_pPlayListi->strPlayListNa

55、me;spPlaylistdNode->setAttribute(CComBSTR(L"name"), CComVariant(strPlayListName);for (int j=0; j<m_pPlayListi->pPlayListItemInfo.size(); j+)CComPtr<IXMLDOMElement> spSongdNode; spDoc->createElement(CComBSTR(L"song"), &spSongdNode);spPlaylistdNode->appendChild(spSongdNode, NULL);CComPtr<IXMLDOMElement> spSingerdNo

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论