0、首先得理解MP3格式文件的结构
简单的就是
MP3 文件大体分为三部分:TAG_V2(ID3V2),音频数据,TAG_V1(ID3V1)
参考此博客:点击打开链接
ID3V1的结构是:
表1:ID3V1结构
--------------------------------------------------------------------
名称 字节 说明
--------------------------------------------------------------------
Tag 3 ID3V1标识符“TAG”的Ascii码
Title 30 歌曲名
Artist 30 歌手名
Album 30 专辑名
Year 4 日期信息
Comment 28 注释信息,有时为30字节
Reserved 1 =0说明有音轨,下一字节就是音轨;≠0表示注释是30个字节
Track 1 音轨(字节型数值),歌曲在专辑里的序号
Genre 1 歌曲风格(字节型数值)
--------------------------------------------------------------------
参考博客链接:点击打开链接
1、为什么会乱码?
看起来是MediaScaner 原生的Flow的缺陷,非中文地区设置,如果编码是GBK格式的则会乱码.
参考此博客:点击打开链接 点击打开链接
2、乱码了怎么解决?
1中的链接是在MediaScanner的源码解决的,我要说的是apk的解决方法
手动读取ID3V1的数据,从而读取出演唱者信息 ,下面看代码:
private synchronized BaseData dealWithMp3Messy(BaseData currentMusic){ String contry = Locale.getDefault().getCountry() ; if((!contry.equalsIgnoreCase("CN")) &&(!contry.equalsIgnoreCase("HK")) &&(!contry.equalsIgnoreCase("TW"))){ return currentMusic; } String currentMp3Path = currentMusic.getPath() ; if(!currentMp3Path.toLowerCase().trim().endsWith("mp3")){ return currentMusic; } RandomAccessFile raf = null ; try{ raf = new RandomAccessFile(currentMp3Path, "r") ; raf.seek(raf.length() - 128) ; byte[] buff = new byte[128] ; raf.read(buff) ; String Tag = new String(buff,0,3,"GBK") ; if(buff.length == 128 && "TAG".equals(Tag)){ String artist = new String(buff,30,33,"GBK").trim() ; Log.i(TAG, "deal with mp3 messy,mp3 artist=******"+artist+"****** and currentMp3Path="+currentMp3Path) ; if(!TextUtils.isEmpty(artist)){ currentMusic.setArtist(artist) ; return currentMusic ; } } }catch(Exception e){ e.printStackTrace(); }finally{ if(raf != null){ try{ raf.close() ; }catch(Exception e){ }finally{ raf = null ; } } } return currentMusic ; }
RamdomAccessFile 可以随意seek到某个字节处来读取文件
读取30到33的演唱者信息出来。就大功告成了。
以上解决了MediaScanner 读取MP3 ID3文件乱码问题