<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 48,comments - 156,trackbacks - 0

    Pymedia 是個 C/C++/Python 的多媒體模塊,可以對包括 mp3/ogg/avi等多媒體格式文件進行編碼解碼和播放,基于 ffmpeg 提供了簡單的 Python 接口。

    一、PyMedia 的下載和安裝

    官方的 PyMedia 模塊已經很久沒有更新了,而且不支持最新的 Python 2.7 和 Python 3.0,使用起來是比較費勁的, 這里有一個網址,里面包含了各種非官方維護的 Python 模塊,其中就有支持 Python 2.7 的 PyMedia 。

    非官方維護 Python 庫

    頁面打開以后,我的小紅傘報告有惡意文件,不知道怎么回事,直接刪除,應該沒什么影響。下載以后安裝,一切正常。

    二、讀取 Mp3 文件

    讀取 mp3 文件就用普通的 python 函數即可,代碼如下:

    data= open( u'鄺美云 - 我和春天有個約會.mp3''rb' ) 
    s
    = f.read(10000)

    這里要特別注意第二行代碼,它讀取了這個 mp3 文件的前 10000 個字節,大概 10K 左右,為什么不是讀取前 1000 個字節,或者全部讀取( 5M 左右)呢?

    我從網上搜索了一下,大概搞明白了是怎么回事,這里我們需要首先了解一下 Mp3 的文件結構

    三、Mp3 文件結構

    MP3文件大體分為三部分:TAG_V2(ID3V2),Frame, TAG_V1(ID3V1) 。

    音頻數據是一幀一幀存儲, 一幀數據的長度為 4 個字節,而 Frame 正是存儲音頻數據幀的部分。

    而文件頭部和文件尾部則存儲了一些其他信息數據,如專輯名稱、歌手、年代等等,這些數據并不能被解碼為音頻。

    對于 PyMedia 來說,至少要讀出文件中的第一幀音頻數據才行,多讀取幾幀沒關系,但是第一幀必須讀取出來,否則后面的程序就沒辦法運行了。

    至于第一幀數據從什么地方開始,這個是不確定的,所以第一次讀取一般多讀一點,保證第一幀能被讀取到。

    那么有沒有辦法來確認下一第一幀是否被讀取到了呢?繼續往下看

    四、解析出音頻數據幀

    讀取出前 10000 個字節的數據后,我們就可以把其中的音頻數據幀解析出來,然后播放,代碼如下:

    1 import pymedia.muxer as muxer
    2 dm= muxer.Demuxer('mp3')
    3 frames= dm.parse( data )
    4 print len(frames)

    第一行代碼導入 muxer 模塊,muxer 谷歌給翻譯成“合成器”,應該是這個意思吧

    第二行代碼創建了一個 Mp3 的 Demuxer 對象 dm

    第三行代碼是重點,它從我們讀取的第一段 10000 個字節的數據中,解析出最初的幾幀,并將這些數據幀存放到 frames 數組中

    第四行代碼測試了 frames 數組的長度,就可以知道 10000 個字節中到底包含了幾幀音頻數據。
    對于這首歌而言是 2 幀, 如果前面一下讀取了全部數據,這里會顯示 1103 ,即這個文件一共包含 1103 幀音頻數據。

    五、設置解碼器

    這里要注意一下,解碼和解析可不是一回事,不要搞混了。看代碼:

    1 import pymedia.audio.acodec as acodec
    2 dec= acodec.Decoder( dm.streams[ 0 ] )

    第一行代碼導入解碼器模塊

    第二行代碼生成解碼器對象,傳入了一個參數 dm.streams[0]

    這里解釋一下,我們在前面解析數據的時候,dm 對象根據數據內容中自動生成了 dm.streams 數組,其實這數組中就包含一個元素,就是 dm.streams[0],他的內容如下:

    {'index'0'block_align'0'type'1'frame_rate_base'1'height'0'channels'0,'width'0'length'-2077252342'sample_rate'0'frame_rate':25'bitrate'0'id'86016}

    說白了就是 mp3 文件的文件信息和編碼信息,在這里,這個參數我們是從文件數據中解析出來的,其實我們自己設置也行,像下面這樣:

    1 params = {'id': acodec.getCodecID('mp3'), 'bitrate'128000'sample_rate'44100'ext''mp3''channels'2}
    2 dec= acodec.Decoder(params)

    六、解碼第一幀音頻數據,并創建音頻輸出對象

    有了解碼器以后,我們就可以首先解碼第一幀音頻數據,并創建音頻輸出對象,代碼如下:

    1 #4.解碼第一幀音頻數據,并創建輸出對象
    2 frame = frames[0]
    3 #音頻數據在 frame 數組的第二個元素中
    4 r= dec.decode( frame[ 1 ] )
    5 print "sample_rate:%s , channels:%s " % (r.sample_rate,r.channels)
    6 import pymedia.audio.sound as sound
    7 snd= sound.Output( r.sample_rate, r.channels, sound.AFMT_S16_LE )

    第一行代碼:前面我們說過,frames 數組中存放了最初的幾幀音頻數據,frames[0] 就是第一幀音頻數據

    第二行代碼:嚴格來說 frames[0] 也是一個數組,它包含五個元素,其中第二個元素 frames[0][1]才是真正的音頻數據,這只是 PyMedia 的一個設計,和 Mp3 音頻幀的數據結構沒關系

    第六行、第七行代碼,創建了一個音頻輸出對象

    七、播放、讀取、解碼......循環下去

    現在我們有了音頻輸出對象,有了第一幀解碼后的數據,就可以直接播放了

    #6.播放
    if r: snd.play( r.data )

    然后繼續讀取數據、解碼、播放,后面的步驟就簡單了,PyMedia 會自動找出數據幀

    #7.繼續讀取、解碼、播放
    while True:
        data
    = f.read(512)
        
    if len(data)>0:
            r
    = dec.decode( data )
            
    if r: snd.play( r.data )
        
    else:
            
    break

    當讀取完最后一幀數據數據以后,要讓程序延時一會在退出,否則最后一幀數據不會被播放出來,程序就結束了

    1 import time
    2 while snd.isPlaying(): time.sleep( .5 )

    完整的代碼

    #1.二進制方法讀取前 10000 個字節,保證能讀到第一幀音頻數據
    = open( u'鄺美云 - 我和春天有個約會.mp3''rb' ) 
    data
    = f.read(10000)

    #2.創建合成器對象,解析出最初的幾幀音頻數據
    import pymedia.muxer as muxer
    dm 
    = muxer.Demuxer('mp3')
    frames 
    = dm.parse( data )
    print len(frames)

    #3.根據解析出來的 Mp3 編碼信息,創建解碼器對象
    import pymedia.audio.acodec as acodec
    dec 
    = acodec.Decoder( dm.streams[ 0 ] )
    #像下面這樣也行
    #
    params = {'id': acodec.getCodecID('mp3'), 'bitrate': 128000, 'sample_rate': 44100, 'ext': 'mp3', 'channels': 2}
    #
    dec= acodec.Decoder(params)


    #4.解碼第一幀音頻數據
    frame = frames[0]
    #音頻數據在 frame 數組的第二個元素中
    r= dec.decode( frame[ 1 ] )
    print "sample_rate:%s , channels:%s " % (r.sample_rate,r.channels)
    #注意:這一步可以直接解碼 r=dec.decode( data),而不用讀出第一幀音頻數據
    #
    但是開始會有一下噪音,如果是網絡流純音頻數據,不包含標簽信息,則不會出現雜音

    #5.創建音頻輸出對象
    import pymedia.audio.sound as sound
    snd 
    = sound.Output( r.sample_rate, r.channels, sound.AFMT_S16_LE )

    #6.播放
    if r: snd.play( r.data )

    #7.繼續讀取、解碼、播放
    while True:
        data 
    = f.read(512)
        
    if len(data)>0:
            r 
    = dec.decode( data )
            
    if r: snd.play( r.data )
        
    else:
            
    break

    #8.延時,直到播放完畢
    import time
    while snd.isPlaying(): time.sleep( .5 )

    //==============================================================================
    posted on 2011-08-07 02:10 左洸 閱讀(5157) 評論(3)  編輯  收藏 所屬分類: Python

    FeedBack:
    # re: 用 PyMedia 解碼并播放 mp3 文件[未登錄]
    2011-08-09 08:38 | greatghoul
    很詳盡呀,還沒有接觸過pymedia,感覺很簡單易用。  回復  更多評論
      
    # re: 用 PyMedia 解碼并播放 mp3 文件
    2011-08-09 16:20 | CHI Flat Iron
    感覺很復雜啊,不過還是謝謝啦  回復  更多評論
      
    # re: 用 PyMedia 解碼并播放 mp3 文件
    2011-08-15 16:03 | 水星家紡
    感覺很復雜啊,不過還是謝謝啦   回復  更多評論
      
    主站蜘蛛池模板: 亚洲欧洲精品无码AV| 亚洲精品国精品久久99热| 亚洲AV日韩AV高潮无码专区| 中文字幕无码精品亚洲资源网| 亚洲精品中文字幕乱码三区| 亚洲资源最新版在线观看| 亚洲视频免费在线播放| 亚洲国产成人精品青青草原| 国产成人精品免费视频大| 亚洲一区二区三区免费视频| 最近中文字幕mv手机免费高清| 永久亚洲成a人片777777 | 精品久久久久久久免费人妻| 亚洲色成人网站WWW永久四虎| 在线免费观看h片| 亚洲成AV人片天堂网无码| 特级无码毛片免费视频尤物| 亚洲综合一区二区精品久久| 无码人妻一区二区三区免费手机| 国产亚洲精AA在线观看SEE| 日韩在线不卡免费视频一区| 久久久久亚洲?V成人无码| 国产精成人品日日拍夜夜免费| 免费一级毛片一级毛片aa| 中文字幕高清免费不卡视频| 四虎免费久久影院| 国产免费一级高清淫曰本片| 久久精品国产亚洲AV香蕉| 国产一精品一AV一免费| 亚洲大香伊人蕉在人依线| 国产成人免费全部网站| 鲁丝片一区二区三区免费| 亚洲一区二区三区偷拍女厕| 在线观看永久免费| 黄色毛片免费观看| 亚洲白色白色永久观看| 曰批视频免费40分钟试看天天| 亚洲五月六月丁香激情| 国产精品色午夜视频免费看| 亚洲av无码兔费综合| 国产AV无码专区亚洲A∨毛片|