wma tag 批量修改[原代码-从wmfsdk中修改]
wma tag 批量修改[原代码-从wmfsdk中修改] 
代码是自己做音乐站点时写的,没有仔细检查,用他修改了近7万的 wma,mp3暂时还没有发现出错。需要的朋友可以自己修改一下。 
效率:5万音乐 70G音乐数据需要差不多3个多小时,程序没有优化。 
编译环境: vc6.0 + WMFSDK9(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmform95/htm/aboutthewindowsmediaformatsdk.asp) 
注意:使用前请先做实验,你的音乐数据搞坏了我是不责任的咯~~~ 
提示:其实程序本身写得不是很好,提供的这些资料你能在wma 中嵌入歌词包括动态歌词,另外wma 中加入script 可以防止偷连,给需要用的人吧! 
包含三个文件 wmatag.cpp, config.txt, input.txt 
config.txt (详细请参见MSDN http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmform95/htm/attributelist.asp ) 
 代码如下:
FileName 
Title 
Author 
Copyright 
CopyrightURL 
Description 
WM/AlbumTitle 
WM/Composer 
WM/Lyrics
input.txt (这个文件是你的批量修改的信息,需要从数据库生成) 
 代码如下:
j:\music\abc\xxxyyy.wma|第十六届Cash流行曲创作大赛-懒醒|杂锦合辑|版权为原作者所有,所有音乐收集自互联网。|http://www.yoursite.com|yoursite....|第十六届Cash流行曲创作大赛|yoursite|歌词 
j:\music\abd\yyyyy.wma|毅忧未尽_预购限量版-左鞋右穿-抢先试听版|陆毅|版权为原作者所有,所有音乐收集自互联网。|http://www.yoursite.com|xxxyy|毅忧未尽_预购限量版|yoursite|歌词 
...
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <tchar.h> 
#include <stdio.h> 
#include <string.h> 
#include <wmsdk.h> 
#pragma comment( lib, "wmvcore.lib" ) 
#pragma comment( lib, "Rpcrt4.lib" ) 
#define FIELD_NUM        9 
#define FIELD_LEN        1024 
char __sFileName[ MAX_PATH ]; 
#ifndef SAFE_RELEASE 
#define SAFE_RELEASE( x )       \ 
    if( NULL != x )             \ 
    {                           \ 
        x->Release( );          \ 
        x = NULL;               \ 
    } 
#endif // SAFE_RELEASE 
#ifndef SAFE_DELETE 
#define SAFE_DELETE( x )        \ 
    if( NULL != x )             \ 
    {                           \ 
        delete x;               \ 
        x = NULL;               \ 
    } 
#endif // SAFE_DELETE 
#ifndef SAFE_ARRAYDELETE 
#define SAFE_ARRAYDELETE( x )   \ 
    if( NULL != x )             \ 
    {                           \ 
        delete [] x;            \ 
        x = NULL;               \ 
    } 
#endif // SAFE_ARRAYDELETE 
#ifndef UNICODE 
HRESULT ConvertMBtoWC( LPCTSTR ptszInString, LPWSTR *ppwszOutString ) 
{ 
    if( ptszInString == NULL || ppwszOutString == NULL ){ 
        return( E_INVALIDARG ); 
    } 
    HRESULT hr          = S_OK; 
    int     nSizeCount  = 0; 
    *ppwszOutString     = NULL; 
    do 
    { 
        // 
        // Get the memory reqd for this string 
        // 
        nSizeCount = MultiByteToWideChar( CP_ACP, 0, ptszInString, -1, NULL, 0 ); 
        if( 0 ==  nSizeCount ) 
        { 
            hr = HRESULT_FROM_WIN32( GetLastError() ); 
            break; 
        } 
        *ppwszOutString = new WCHAR[ nSizeCount ]; 
        if( NULL == *ppwszOutString ) 
        { 
            hr = HRESULT_FROM_WIN32( GetLastError() ); 
            break; 
        } 
        if( 0 == MultiByteToWideChar( CP_ACP, 0, ptszInString, -1, *ppwszOutString, nSizeCount ) ) 
        { 
            hr = HRESULT_FROM_WIN32( GetLastError() ); 
            break; 
        } 
    } 
    while( FALSE ); 
    if( FAILED( hr ) ) 
    { 
        SAFE_ARRAYDELETE( *ppwszOutString ); 
        _tprintf( _T( "Internal error ( hr=0x%08x )\n" ), hr ); 
    } 
    return( hr ); 
} 
#endif // UNICODE 
HRESULT editorOpen( WCHAR* _wma_file, IWMMetadataEditor ** ppEditor, IWMHeaderInfo ** ppHeaderInfo ) 
{ 
    if( ( NULL == _wma_file ) || ( NULL == ppEditor ) ){ 
        return( E_INVALIDARG ); 
    } 
    HRESULT hr = S_OK; 
    do 
    { 
        hr = WMCreateEditor( ppEditor ); 
        if( FAILED( hr ) ){ 
            _tprintf( _T( "Could not create Metadata Editor ( hr=0x%08x ).\n" ), hr ); 
            break; 
        } 
        hr = ( *ppEditor )->Open( _wma_file ); 
        if( FAILED ( hr ) ){ 
            _tprintf( _T( "Could not open the file %ws ( hr=0x%08x ).\n" ),  
                _wma_file, hr ); 
            break; 
        } 
        if( NULL != ppHeaderInfo ){ 
            hr = ( *ppEditor )->QueryInterface( IID_IWMHeaderInfo,  
                                                (void **)ppHeaderInfo ); 
            if( FAILED( hr ) ){ 
                _tprintf( _T( "Could not QI for IWMHeaderInfo ( hr=0x%08x ).\n" ), hr ); 
                break; 
            } 
        } 
    } 
    while( FALSE ); 
    return( hr ); 
} 
HRESULT SetAttrib( WCHAR * _wma_file, WCHAR * pName, WCHAR * pValue ) 
{ 
        WORD wStreamNum = 0; 
        WORD wAttribType = WMT_TYPE_STRING; 
    if( ( NULL == _wma_file ) || ( NULL == pName ) || ( NULL == pValue ) ){ 
        return( E_INVALIDARG ); 
    } 
    HRESULT hr = S_OK; 
    IWMMetadataEditor   * pEditor       = NULL; 
    IWMHeaderInfo       * pHeaderInfo   = NULL; 
    BYTE*               pbAttribValue   = NULL; 
    WORD                wAttribValueLen = 0; 
    WMT_ATTR_DATATYPE   AttribDataType  = ( WMT_ATTR_DATATYPE ) wAttribType; 
    DWORD               dwAttribValue   = 0; 
    WORD                wAttribValue    = 0; 
    QWORD               qwAttribValue   = 0; 
    BOOL                fAttribValue    = 0; 
    do 
    { 
        hr = editorOpen( _wma_file, &pEditor, &pHeaderInfo ); 
        if(FAILED( hr ) ){ 
            break; 
        } 
                /* 
                        Attrib type = string...         
                */ 
        wAttribValueLen = ( wcslen( pValue ) + 1 )* sizeof( WCHAR ); 
        pbAttribValue = (BYTE *)pValue; 
        hr = pHeaderInfo->SetAttribute( wStreamNum, 
                                        pName, 
                                        AttribDataType,                                         
                                        pbAttribValue, 
                                        wAttribValueLen ); 
        if( FAILED( hr ) ){ 
            _tprintf( _T( "SetAttribute failed for Attribute name %ws ( hr=0x%08x ).\n" ),  
                pName, hr ); 
            break; 
        } 
        hr = pEditor->Flush(); 
        if( FAILED( hr ) ){ 
            _tprintf( _T( "Could not flush the file %ws ( hr=0x%08x ).\n" ),  
                _wma_file, hr ); 
            break; 
        } 
        hr = pEditor->Close(); 
        if( FAILED( hr ) ){ 
            _tprintf( _T( "Could not close the file %ws ( hr=0x%08x ).\n" ),  
                _wma_file, hr ); 
            break; 
        } 
    } 
    while( FALSE ); 
    SAFE_RELEASE( pHeaderInfo ); 
    SAFE_RELEASE( pEditor ); 
    return( hr ); 
} 
HRESULT __SetAttrib( WCHAR * _wma_file, WCHAR ** pName, WCHAR ** pValue ) 
{ 
        WORD wStreamNum = 0; 
        WORD wAttribType = WMT_TYPE_STRING; 
        int i; 
    if( ( NULL == _wma_file ) || ( NULL == pName ) || ( NULL == pValue ) ){ 
        return( E_INVALIDARG ); 
    } 
    HRESULT hr = S_OK; 
    IWMMetadataEditor   * pEditor       = NULL; 
    IWMHeaderInfo       * pHeaderInfo   = NULL; 
    BYTE*               pbAttribValue   = NULL; 
    WORD                wAttribValueLen = 0; 
    WMT_ATTR_DATATYPE   AttribDataType  = ( WMT_ATTR_DATATYPE ) wAttribType; 
    DWORD               dwAttribValue   = 0; 
    WORD                wAttribValue    = 0; 
    QWORD               qwAttribValue   = 0; 
    BOOL                fAttribValue    = 0; 
    do 
    { 
        hr = editorOpen( _wma_file, &pEditor, &pHeaderInfo ); 
        if(FAILED( hr ) ){ 
            break; 
        } 
                for( i = 1; i < FIELD_NUM; i ++ ){ 
                                                //SetAttrib( _wma_file, attribNames[ i ], fields[ i ] ); 
                                                //printf( "%d: %s\n", i, fields[ i ] ); 
                        /* 
                                Attrib type = string...         
                        */ 
                wAttribValueLen = ( wcslen( pValue[ i ] ) + 1 )* sizeof( WCHAR ); 
                pbAttribValue = (BYTE *)pValue[ i ]; 
                hr = pHeaderInfo->SetAttribute( wStreamNum, 
                                        pName[ i ], 
                                        AttribDataType,                                         
                                        pbAttribValue,  
                                        wAttribValueLen ); 
                if( FAILED( hr ) ){ 
                    _tprintf( _T( "SetAttribute failed for Attribute name %ws ( hr=0x%08x ).\n" ), pName[ i ], hr ); 
                    break; 
                } 
                } 
        hr = pEditor->Flush(); 
        if( FAILED( hr ) ){ 
            _tprintf( _T( "Could not flush the file %ws ( hr=0x%08x ).\n" ),  
                _wma_file, hr ); 
            break; 
        } 
        hr = pEditor->Close(); 
        if( FAILED( hr ) ){ 
            _tprintf( _T( "Could not close the file %ws ( hr=0x%08x ).\n" ),  
                _wma_file, hr ); 
            break; 
        } 
    } 
    while( FALSE ); 
    SAFE_RELEASE( pHeaderInfo ); 
    SAFE_RELEASE( pEditor ); 
    return( hr ); 
} 
bool get_info( WCHAR **fields, int num , char *input ){ 
        int seg = 0; 
        char *s = input; 
        char buffer[ 1024 * 4 ] = { 0x00 }; 
        __sFileName[ 0 ] = 0x00; 
        for( char *p = input; *p != 0x00 ; p ++ ){ 
                if( *p == '|' ){ 
                        *p = 0x00; 
                        strcpy( buffer, s ); 
                        if( __sFileName[ 0 ] == 0x00 ) 
                                strcpy( __sFileName, s ); 
                HRESULT hr = ConvertMBtoWC( buffer, &fields[ seg ] ); 
                if( FAILED( hr ) ){ 
                           break; 
                } 
                buffer[ 0 ] = 0x00;                 
                        //strcpy( fields[ seg ], s ); 
                        s = p + 1; 
                        seg ++; 
                        if( seg == num - 1 ){ 
                                if( *s != 0x00 ){ 
                                        strcpy( buffer, s ); 
                                        hr = ConvertMBtoWC( buffer, &fields[ seg ] ); 
                                        //strcpy( fields[ seg ], s ); 
                                } 
                                break; 
                        } 
                } 
        } 
        if( seg == num - 1 ) 
                return true; 
        else 
                return false; 
} 
int loadConfig( WCHAR **attribNames ){ 
        char buffer[ 1024 ]; 
        FILE *fp; 
        int i = 0; 
        HRESULT hr = S_OK; 
        fp = fopen( "config.txt", "rb" ); 
        if( !fp ){ 
                perror( "fopen( config.txt )" ); 
                return -1; 
        } 
        while( !feof( fp )){ 
                if( fgets( buffer, sizeof( buffer ), fp ) ){ 
                        if( strlen( buffer ) < 3 ) 
                                continue; 
                        for( int j = 0; j < (int)strlen( buffer ); j ++ ){ 
                                if( buffer[ j ] == 0x0a || buffer[ j ] == 0x0d ) 
                                        buffer[ j ] = 0x00; 
                        } 
                        hr = ConvertMBtoWC( buffer, &attribNames[ i ] ); 
                        if( FAILED( hr ) ) 
                                break; 
                        else 
                                i ++; 
                } 
        } 
        fclose( fp ); 
        if( FAILED( hr ) ) 
                return -1; 
        else 
                return i; 
}
int main( void ){ 
        WCHAR *fields[ FIELD_NUM ]; 
        WCHAR *attribNames[ 128 ] = { 0x00 }; 
        int i; 
        int j = 0; 
        int fieldNum = loadConfig( attribNames ); 
        printf( "%d\n", fieldNum ); 
        for( i = 0; i < 128; i ++ ){ 
                if( attribNames[ i ] ) 
                        _tprintf( _T( "%ws %ws\n"), attribNames[ i ], _T( "hello go....") ); 
        } 
        char input[ 1024 * 4 ]; 
        FILE *fp = fopen( "input.txt", "rb" ); 
        if( !fp ){ 
                perror( "fopen( )" ); 
                return -1;         
        } 
        while( !feof( fp ) ){ 
                input[ 0 ] = 0x00; 
                if( fgets( input, sizeof( input ), fp ) ){ 
                        for( i = 0; i < FIELD_NUM; i ++ ) 
                                fields[ i ] = NULL; 
                        j ++; 
                        if( j % 100 == 0 ) 
                                printf( "files: %d\n", j ); 
                        bool st = get_info( fields, FIELD_NUM, input ); 
                        if( st == false ) 
                                printf( "status: %s\n", st?"true":"false" ); 
                        //printf( "status: %s\n", st?"true":"false" ); 
                        if( st ){ 
                                WCHAR * _wma_file = fields[ 0 ]; 
                                FILE *fp = fopen( __sFileName, "rb" ); 
                                if( fp ){ 
                                        fclose( fp ); 
                                        //puts( __sFileName ); 
                                        __SetAttrib( _wma_file, attribNames, fields ); 
                                        /* 
                                        for( i = 1; i < FIELD_NUM; i ++ ){
SetAttrib( _wma_file, attribNames[ i ], fields[ i ] ); 
                                                //printf( "%d: %s\n", i, fields[ i ] ); 
                                        } 
                                        */ 
                                } 
                        } 
                        for( i = 0; i < FIELD_NUM; i ++ ) 
                                SAFE_ARRAYDELETE( fields[ i ] );                 
                }                                 
        } 
        fclose( fp ); 
        return 0; 
}

