65.9K
CodeProject 正在变化。 阅读更多。
Home

Winamp 播放列表信息提示

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (3投票s)

2008年12月12日

CPOL

4分钟阅读

viewsIcon

34711

downloadIcon

572

用于快速预览音乐播放列表的信息提示外壳扩展

screen1.png

引言

有一些非常有用的实用程序可以扩展围绕 MP3 和其他媒体文件的 Shell 功能,例如 AudioShell。它们将媒体文件的元数据预览和编辑集成到 Windows Shell 本身,无需任何外部应用程序。最值得注意的 Shell 扩展示例是媒体文件元数据(如标题和艺术家信息)的预览。

本文遵循了相同的思路。本文介绍了一个 Shell 扩展,该扩展增加了对 PLS、M3U 和 M3U8 音乐播放列表的提示信息预览。PLS(由 Winamp 引入)和 M3U 是最广泛使用的播放列表格式,被 Winamp、Windows Media Player 和许多其他播放器支持。M3U 和 PLS 不支持 Unicode,而 M3U8 是一种 UTF8 扩展的 M3U 文件格式。

Vista Shell

XP 和 Vista 提示信息之间有一个关键区别。XP 中的提示信息字符数没有限制,而 Vista 对可显示字符数设置了限制。Vista 提示信息最多限制为约 900 个字符,即每行约 15 行,每行 65 个字符 + 第 16 行 5 个字符,如下图所示(来自生成长字符串以供提示信息的特殊测试)。

Vista infotip limit

很难确定换行符 ('\n') 是否包含在计数中,但它们很可能被包含在内。

因此,播放列表解析和提示信息生成受到限制,以便在 Vista 和 XP 上都能正确显示提示信息。

Big infotip in Vista    Big infotip in XP

我在这里没有包含 XP 上大型提示信息的屏幕截图,因为提示信息可以占用整个屏幕(如果足够大)。我不知道它会超出屏幕边界多少。

如果您系统中没有安装亚洲或其他宽字符语言文件,您可能会丢失一些字符,如果播放列表最初是用宽字符保存的(Vista 和 XP 屏幕截图)。

Full Unicode SupportMissing wide characters

代码

此代码建立在 Dino Esposito 的优秀文章 Windows 2000 UI Innovations 的代码之上。强烈建议您先阅读它,因为它解释了许多我在这里不会涵盖的基本细节。有关 PLS 和 M3U/M3U8 格式,请参阅 Winamp 论坛上的 非官方规范。PLS 文件使用 Richard J. Wagner 的 ConfigFile 类 进行解析。

该项目使用 VC 2005 Express + Platform SDK2003 R2 + WTL 8.0 构建,并且很可能在 VC 2008 中无需任何更改即可构建。

主要的播放列表解析框架位于 PlaylistParser.cpp 中。播放列表格式由文件扩展名确定,并选择相应的解析函数。

PLAYLIST_TYPE C_PlaylistParser::getType(CString fpl)
{
	fpl.MakeLower();
	if (fpl.IsEmpty()) return NOTPLS;
	if (fpl==_T("m3u")) return M3U;
	if (fpl==_T("m3u8")) return M3U;
	......
return NOTPLS;
}

int C_PlaylistParser::process(CString fpls)
{
	playlistFile.Split(fpls); 
	playlistFile.ext_nodot.MakeLower();
try
{
	playlistType=getType(playlistFile.ext_nodot);
	switch (playlistType)
		{
		case M3U:
		parseM3U();
		break;
		case PLS:
		parsePLS();
		break;
		......
		default:
		break;
		}
	buildPlaylist();
}
catch (...) {return FALSE;}
return TRUE;
}

M3U 和 M3U8 都通过将文本行传递给 MultiByteToWideChar 并使用 CP_UTF8 标志来处理。

请注意,PLS 规范声明条目区分大小写。

buildPlaylist() 函数将存储在 vector 中的信息转换为具有以下布局的提示信息。

<track#>.<artist, title>  <track playtime ##:##>

....
--------------------------------------------
Total playing time: ##:##:##
Size: ######

如果播放列表处理完全失败,将显示一个通用的提示信息(文件类型、大小)。

请注意,文件大小是通过 GetFileSize 确定的,该函数仅对小于 2GB 的文件有效。虽然这不是一个好习惯,但播放列表不太可能大于 2 GB。

最后,我们必须不要忘记在 CBmpTip::GetBitmapInfo 方法中使用 try/catch 块,以防止任何可能的错误导致 Explorer 崩溃(例如,在使用中拔出 USB 驱动器)。在源代码包中有一个小的测试项目(*PLS.sln*)用于测试解析器代码,因为在 Windows Explorer 中调试 Shell 扩展可能非常不方便。

对于某些媒体类型(如 *.ogg),播放列表可能会省略曲目时长,如果保存应用程序无法确定的话。如果文件路径指向网络电台流,则曲目名称显示 URL,曲目时长不确定。

Web radio playlist

Vista 和 UAC

为了使此 Shell 扩展能与 UAC 良好协作,必须将 DLL 添加到已知 DLL 列表中。

HKLM
{
    NoRemove Software
    {
        NoRemove Microsoft
        {
            NoRemove Windows
            {
                NoRemove CurrentVersion
                {
                    NoRemove 'Shell Extensions'
                    {
                        NoRemove Approved
                        {
                            val {A191B386-C1C7-4fb5-AD9D-6979C21CE44B} = s 'PlsTip Class'
...

代码重用

要将解析扩展到其他播放列表格式(如 wpl 等),您需要将您的提示信息生成函数放在 CBmpTip::GetBitmapInfo 成员中,在 PlaylistGlobals.h 中的 PLAYLIST_TYPE 枚举和 C_PlaylistParser::getType 中添加新的文件扩展名,并在 switch(playlistType) 块中添加新的解析函数。

还需要在 BmpTip.rgsBmpTip.idl 文件中添加必要的注册表项。

要创建一个全新的提示信息扩展,请将您的新提示信息生成函数放在 CBmpTip::GetBitmapInfo 成员中,并更改 BmpTip.rgsBmpTip.idl 文件中的 CLSID。

在可能的情况下实现了有限的错误纠正,但它不像普通程序那样是防错的,因为我不期望解析手工制作的播放列表(可能包含错误)。该代码最适合应用程序生成的播放列表,因为它们不太可能包含结构性错误。项目包附带了一些测试文件,因此您可以进行自己的测试。

© . All rights reserved.