国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

無外部控件制作多媒體播放器(二)

2024-07-21 02:16:09
字體:
來源:轉載
供稿:網友

本來想寫點進度控制與音量調整的代碼的,后來發現還是太簡單了,就是幾個mci命令,來回搬弄,自己都沒興趣寫下去。所以我想還是寫些獨門一點的:音樂信息的讀取!

目前常見的主流音樂格式就兩種,mp3與wma,它們都有在文件中保存音樂信息的特定格式,mp3使用的當然是家喻戶曉的id3格式,分為v1與v2兩個版本;wma是ms的寵兒,它只是asf格式的一個分支,當然遵循asf的包裝規則。

怎么獲取它們包含的音樂信息呢?一般是自己讀取,當然xp系統開始提供了音樂文件的詳細信息資料,利用fso可以真接從系統那里讀取到,這不在本文范圍,畢竟不用控件更自由,通用性更好。所以,有必要去深入一下這幾種音樂信息格式。還是用代碼說話吧,先說說mp3的id3v1與id3v2的格式。

id3v1很簡單,共128個字節,寫在文件尾部,格式如下:

private type mp3id3v1
    header as string * 3
    title as string * 30
    artist as string * 30
    album as string * 30
    year as string * 4
    comment as string * 30
    genre as string * 1
end type

id3v2是后來出現的,可擴展性很強,寫在文件頭部,采用標簽組格式,分兩部分,一是標簽組的總頭部,一是每個子標簽的頭部,分別定義如下:

private type mp3id3v2
    header as string * 3
    ver as byte
    revision as byte
    flag as byte
    size(3) as byte
end type

private type mp3id3v2tag
    tag as string * 4
    size(3) as byte
    flag(1) as byte
end type

為了組織音樂信息的方便,我還定義了一個自己的結構,以便于使用:

'音樂類型
private enum mediatype
    mcimidi = 1
    mcimp3 = 2
    mciasf = 4
    mcivideo = 8
    mciwave = 16
end enum
'裝載音樂信息的結構
private type musicinfo
    filename as string
    musictype as mediatype
    title as string
    artist as string
    album as string
    year as string
    lyrics as string
    writer as string
    composer as string
    bits as string
    sample as string
    length as long
end type

'我習慣于用代碼說明問題,所以還是看看代碼吧

private function getmusicinfo(udtinfo as musicinfo) as boolean
    dim strfilename as string, a() as string, i as long
    with udtinfo
        strfilename = dir(.filename, vbnormal or vbhidden or vbreadonly or vbsystem or vbarchive)
        if strfilename = vbnullstring then exit function
        .musictype = getmcitype(strfilename)
        if .musictype and mcimp3 then
            getmusicinfo = getmp3info(udtinfo)
        elseif .musictype and mciasf then
            getmusicinfo = getasfinfo(udtinfo)
        end if
    end with
end function

private function getmcitype(strfilename as string) as mediatype
    dim ext as string
    if strfilename <> vbnullstring then
        ext = lcase$(mid$(strfilename, instrrev(strfilename, ".")))
        select case ext
            case ".mpg", ".mpeg", ".avi", ".mpe", ".mpa", ".m1v", ".ifo", ".vob"
                getmcitype = mcivideo
            case ".mp3"
                getmcitype = mcimp3
            case ".wav", ".snd", ".aif", ".au", ".aifc", ".aiff"
                getmcitype = mciwave
            case ".asf", ".wma", ".wm", ".wmd"
                getmcitype = mciasf
            case ".wmv"
                getmcitype = mciasf or mcivideo
            case ".mid", ".midi", ".rmi"
                getmcitype = mcimidi
        end select
    end if
end function


private function getmp3info(udtinfo as musicinfo) as boolean
    dim freeno as long, n(1) as byte, b() as byte, tmpinfo as musicinfo
    dim power as long, v as long, j as long, tagh as mp3id3v2tag
    dim id3 as mp3id3v1, s as string, pos as long, id32 as mp3id3v2
    dim sz as long, s1 as string
    tmpinfo = udtinfo
    on error goto exitg
    freeno = freefile
    open tmpinfo.filename for binary as #freeno
    with tmpinfo
        pos = lof(freeno) - 127
        if pos > 0 then
            get #freeno, pos, id3
            if ucase$(id3.header) = "tag" then
                s = trim$(replace$(id3.title, vbnullchar, vbnullstring))
                if len(s) > 0 then
                    s = replace$(s, "-", vbnullstring)
                    s = replace$(s, "——", vbnullstring)
                    s = replace$(s, ".mp3", vbnullstring, , , vbtextcompare)
                    .title = s
                end if
                s = trim$(replace$(id3.artist, vbnullchar, vbnullstring))
                if len(s) > 0 then
                    .title = replace$(.title, s, vbnullstring)
                    .artist = s
                end if
                s = trim$(replace$(id3.album, vbnullchar, vbnullstring))
                if len(s) > 0 then .album = s
                s = trim$(replace$(id3.year, vbnullchar, vbnullstring))
                if len(s) > 0 then .year = s
            end if
        end if
        get #freeno, 1, id32
        if id32.header = "id3" then
            sz = (id32.size(1) and &h7f) * &h400 + (id32.size(2) and &h7f) * &h80 + (id32.size(3) and &h7f)
            pos = sz + 10
            s1 = string(4, vbnullchar)
            get #freeno, , tagh
            do while not (tagh.tag = s1 or seek(freeno) > sz + 10)
                j = tagh.size(1) * &h10000 + tagh.size(2) * &h100 + tagh.size(3)
                if j > 0 then
                    redim b(j - 1)
                    get #freeno, , b
                    s = strconv(b, vbunicode)
                    s = trim$(replace$(s, vbnullchar, ""))
                    select case tagh.tag
                    case "tit2"
                        .title = s
                    case "tpe1"
                        .artist = s
                    case "talb"
                        .album = s
                    case "tcom"
                        .composer = s
                    case "text"
                        .writer = s
                    case "tyer"
                        .year = s
                    case "uslt"
                        s = replace$(s, "  ", " ")
                        if lcase$(left$(s, 3)) = "chi" then
                            .lyrics = mid$(s, 4)
                        elseif lcase$(left$(s, 3)) = "eng" then
                            .lyrics = mid$(s, 4)
                        else
                            .lyrics = s
                        end if
                    end select
                end if
                get #freeno, , tagh
            loop
        else
            pos = 1
        end if
        get #freeno, pos, n
        sz = pos
        if not (n(0) = &hff and n(1) >= &hfa and n(1) <= &hff) then
            do while not (n(0) = &hff and n(1) = &hfb)
                pos = pos + 1
                if seek(freeno) - sz > 8192 then goto exitg
                get #freeno, pos, n
            loop
        end if
        get #freeno, , n
           
        v = 0
        for j = 4 to 7
            power = 2 ^ j
            if (n(0) and power) = power then v = v + power
        next
        v = v / 16
        .bits = trim$(mid$("144 320 32  48  56  64  80  96  112 128 160 192 224 256 320 ", v * 4 + 1, 4)) & "kbps"
        v = 0
        for j = 2 to 3
            power = 2 ^ j
            if (n(0) and power) = power then v = v + power
        next
        v = v / 4
        .sample = trim$(mid$("44 48 32 ?? ", v * 3 + 1, 3)) & "khz"
    end with
    udtinfo = tmpinfo
    getmp3info = true
exitg:
    close #freeno
end function

還有個asf格式,有點煩,下篇再做說明吧!
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 秭归县| 灵石县| 灵川县| 慈溪市| 乌拉特后旗| 泾源县| 本溪| 吴川市| 潮州市| 栾城县| 开封县| 大关县| 健康| 尚义县| 买车| 马尔康县| 山西省| 新宾| 柘城县| 延寿县| 红桥区| 福安市| 丹东市| 富民县| 淳安县| 海晏县| 新乡市| 台南县| 建阳市| 阿坝县| 定州市| 汽车| 岢岚县| 台南市| 乐亭县| 新竹市| 惠州市| 乌拉特前旗| 凉山| 济宁市| 阜阳市|