[C++] 将 mp3 等音乐资源以资源形式嵌入 exe 文件中

简介:


 

引用:http://www.easyx.cn/skills/View.aspx?id=6

本文讲解怎样将 mp3 等音乐资源以资源形式嵌入 exe 文件中,并通过 mciSendString 调用。嵌入 mp3 和嵌入图片略有不同,将图片嵌入到 exe 中,以及访问嵌入 exe 中的图片,请参考:http://www.easyx.cn/skills/View.aspx?id=6

 

【一、以资源文件形式嵌入 exe】

关于“资源文件”的介绍和“将 mp3 以资源形式嵌入 exe 文件中”的步骤,请仿照 http://www.easyx.cn/skills/View.aspx?id=6。

 

【二、播放资源文件中的 mp3】

1. 思路

查看 MSDN 中关于 mciSendString 的使用,发现并不支持直接读取资源文件中的媒体文件,也不支持读取内存中的媒体文件。因此,我们需要提取资源

文件中的 mp3 为成临时文件,然后调用 mciSendString 播放,播放结束后再删掉这个临时文件。

2. 提取资源文件中的为临时文件

这个步骤不算复杂,只需要将资源文件中的资源读取到内存中,然后将内存数据写入文件即可。针对资源 ID 为字符串和宏两种形式,核心代码如下:

复制代码
 1 //////////////////////////////////////////////////////////////////
 2 // 提取指定模块中的资源文件
 3 // 参数:
 4 //     strDstFile:     目标文件名。提取的资源将保存在这里;
 5 //     strResType:     资源类型;
 6 //     strResName:     资源名称;
 7 // 返回值:
 8 //     true: 执行成功;
 9 //     false: 执行失败。
10 bool ExtractResource(LPCTSTR strDstFile, LPCTSTR strResType, LPCTSTR strResName)
11 {
12     // 创建文件
13     HANDLE hFile = ::CreateFile(strDstFile, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
14     if (hFile == INVALID_HANDLE_VALUE)
15         return false;
16 
17     // 查找资源文件中、加载资源到内存、得到资源大小
18     HRSRC    hRes    = ::FindResource(NULL, strResName, strResType);
19     HGLOBAL    hMem    = ::LoadResource(NULL, hRes);
20     DWORD    dwSize    = ::SizeofResource(NULL, hRes);
21 
22     // 写入文件
23     DWORD dwWrite = 0; // 写入大小
24     ::WriteFile(hFile, hMem, dwSize, &dwWrite, NULL);
25     ::CloseHandle(hFile);
26 
27     return true;
28 }
复制代码

3. 使用 mciSendString 播放音乐

这一步利用第 2 步导出的文件名,直接用 mciSendString 播放。mciSendString 的使用方法请参考:http://www.easyx.cn/skills/View.aspx?id=44

4. 删除临时文件

临时文件如果不再使用,请及时删除。可以使用 windows api 函数 DeleteFile。

 

【三、范例 1】

下面是一个完整的范例项目,该项目中有一个 "MP3" 类型的资源文件,资源 ID 为字符串 "background.mp3",播放这个 mp3 的范例代码如下:

复制代码
 1 ///////////////////////////////////////////////////
 2 // 程序名称:范例:播放以资源形式保存的 mp3 音乐
 3 // 编译环境:Visual C++ 6.0 / 2010,EasyX 2011惊蛰版
 4 // 作  者:yangw80 <yw80@qq.com>
 5 // 最后修改:2011-10-7
 6 //
 7 #include <graphics.h>
 8 #include <conio.h>
 9 #include <stdio.h>
10 #pragma comment(lib, "Winmm.lib")    // 引用 Windows Multimedia API
11 // #include "resource.h"     // 注:如果资源 ID 为宏定义,请取消这行注释
12 
13 
14 //////////////////////////////////////////////////////////////////
15 // 提取指定模块中的资源文件
16 // 参数:
17 //     strDstFile:     目标文件名。提取的资源将保存在这里;
18 //     strResType:     资源类型;
19 //     strResName:     资源名称;
20 // 返回值:
21 //     true: 执行成功;
22 //     false: 执行失败。
23 bool ExtractResource(LPCTSTR strDstFile, LPCTSTR strResType, LPCTSTR strResName)
24 {
25     // 创建文件
26     HANDLE hFile = ::CreateFile(strDstFile, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
27     if (hFile == INVALID_HANDLE_VALUE)
28         return false;
29 
30     // 查找资源文件中、加载资源到内存、得到资源大小
31     HRSRC    hRes    = ::FindResource(NULL, strResName, strResType);
32     HGLOBAL    hMem    = ::LoadResource(NULL, hRes);
33     DWORD    dwSize    = ::SizeofResource(NULL, hRes);
34 
35     // 写入文件
36     DWORD dwWrite = 0; // 返回写入字节
37     ::WriteFile(hFile, hMem, dwSize, &dwWrite, NULL);
38     ::CloseHandle(hFile);
39 
40     return true;
41 }
42 
43 
44 // 主函数
45 void main()
46 {
47     // 初始化图形窗口
48     initgraph(640, 480);
49 
50     // 输出提示信息
51     outtextxy(0, 0, _T("按任意键开始播放"));
52     _getch();
53 
54     // 产生临时文件的文件名
55     TCHAR tmpmp3[_MAX_PATH];
56     ::GetTempPath(_MAX_PATH, tmpmp3);
57     _tcscat(tmpmp3, _T("testapp_background.mp3"));     // VC2008、VC2010 请用 _tcscat_s 函数
58 
59     // 将 MP3 资源提取为临时文件
60     ExtractResource(tmpmp3, _T("MP3"), _T("background.mp3"));
61     // 注:如果 MP3 资源的 ID 为宏 IDR_BACKGROUND,这样做:
62     // ExtractResource(tmpmp3, _T("MP3"), MAKEINTRESOURCE(IDR_BACKGROUND));
63 
64     // 打开音乐
65     TCHAR mcicmd[300];
66     _stprintf(mcicmd, _T("open \"%s\" alias mymusic"), tmpmp3);     // VC2008、VC2010 请用 _stprintf_s 函数
67     mciSendString(mcicmd, NULL, 0, NULL);
68 
69     // 播放音乐
70     mciSendString(_T("play mymusic"), NULL, 0, NULL);
71 
72     // 输出提示信息
73     outtextxy(0, 0, _T("按任意键停止播放"));
74     _getch();
75 
76     // 停止播放并关闭音乐
77     mciSendString(_T("stop mymusic"), NULL, 0, NULL);
78     mciSendString(_T("close mymusic"), NULL, 0, NULL);
79 
80     // 删除临时文件
81     DeleteFile(tmpmp3);
82     
83     // 输出提示信息
84     outtextxy(0, 0, _T("按任意键退出程序"));
85     _getch();
86     
87     // 关闭图形窗口
88     closegraph();
89 }
复制代码



相关文章
|
9天前
|
C++
C/C++给文件加crc校验
C/C++给文件加crc校验
33 1
|
9天前
|
存储 C++
基于C++的简易文件压缩与解压缩工具设计与实现
基于C++的简易文件压缩与解压缩工具设计与实现
22 3
|
1天前
|
Java C++ Python
C++ 使用getline()从文件中读取一行字符串
`getline()` 是 C++ 中 `istream` 类的一个方法,被 `fstream` 和 `ifstream` 继承,用于从文件中读取一行字符串。它有两种语法:一种是从文件读取 `bufSize-1` 个字符到 `buf` 直到 `\n`,另一种是读到指定分隔符 `delim`。如果文件中的字符数量超过 `bufSize`,会导致读取失败。示例代码展示了如何使用 `getline()` 读取和打印文件内容。通过循环调用 `getline()`,可以连续读取文件的多行数据。
9 0
|
3天前
|
存储 C++ iOS开发
C++ 文件和流
C++ 文件和流
8 0
|
4天前
|
C++
C++程序对数据文件的操作与文件流
C++程序对数据文件的操作与文件流
12 0
|
9天前
|
数据采集 数据安全/隐私保护 C++
通过C++和libcurl下载网易云音乐音频文件的5个简单步骤
本文将介绍如何通过C和libcurl库下载网易云音乐的音频文件。我们将通过5个简单步骤完成这个任务,同时会使用爬虫代理IP技术来绕过这些网络限制,确保下载的顺利进行。为此,我们将参考爬虫代理的域名、端口、用户名和密码进行设置。网易云音乐作为一个不断发展的音乐平台,其丰富的资源和智能化服务将持续吸引大量用户,而掌握如上所述的下载技巧也将助力开发者更好地利用这些资源。
通过C++和libcurl下载网易云音乐音频文件的5个简单步骤
|
9天前
|
机器学习/深度学习 JSON 编译器
C++ 资源大全:标准库、Web框架、人工智能等 | 最全整理
C++ 资源列表,内容包括: 标准库、Web应用框架、人工智能、数据库、图片处理、机器学习、日志、代码分析等
57 1
|
9天前
|
C++ 数据格式
【C++】C++中的【文件IO流】使用指南 [手把手代码演示] & [小白秒懂]
【C++】C++中的【文件IO流】使用指南 [手把手代码演示] & [小白秒懂]
【C++】C++中的【文件IO流】使用指南 [手把手代码演示] & [小白秒懂]
|
9天前
|
开发工具 对象存储 Android开发
对象存储oss使用问题之C++使用OSS SDK时遍历OSS上的文件时崩溃如何解决
《对象存储OSS操作报错合集》精选了用户在使用阿里云对象存储服务(OSS)过程中出现的各种常见及疑难报错情况,包括但不限于权限问题、上传下载异常、Bucket配置错误、网络连接问题、跨域资源共享(CORS)设定错误、数据一致性问题以及API调用失败等场景。为用户降低故障排查时间,确保OSS服务的稳定运行与高效利用。
34 0
|
9天前
|
C++ Python
【C++/Python】C++调用python文件
【C++/Python】C++调用python文件