前言:
最近在做实训,写一个音乐播放器,将文件存储在服务端,然后将相应的数据信息添加到数据库中。不想一个个手动添加,所以在百度之后发现MP3文件本身是只带这些信息的。
我对下述代码进行了改进. 具体项目代码地址
主要变动.
1. 使用由获取ID3v1中的信息变成了获取,ID3v2中的信息.
2. 去除了字符串过滤.
class MusicUtil {
private static final String SONG_NAME_KEY = "TIT2";
private static final String ARTIST_KEY = "TPE1";
private static final String ALBUM_KEY = "TALB";
/**
* 通过歌曲文件地址, 获取歌曲信息
*
* @param filePath 歌曲文件地址
* @return 歌曲信息
* @throws Exception 可能抛出空指针异常
*/
static Music getMusicInfo(String filePath) throws Exception {
Music music = null;
try {
MP3File mp3File = (MP3File) AudioFileIO.read(new File(filePath));
MP3AudioHeader audioHeader = (MP3AudioHeader) mp3File.getAudioHeader();
// 歌曲名称
String songName = getInfoFromFrameMap(mp3File, SONG_NAME_KEY);
// 歌手名称
String artist = getInfoFromFrameMap(mp3File, ARTIST_KEY);
// 歌曲专辑
String album = getInfoFromFrameMap(mp3File, ALBUM_KEY);
// 播放时长
int duration = audioHeader.getTrackLength();
// 封装到music对象
music = new Music(songName, artist, album, duration, filePath);
} catch (Exception e) {
e.printStackTrace();
System.out.println("文件读取失败!" + e);
}
return music;
}
/**
* 通过键值,获取歌曲中对应的字段信息
*
* @param mp3File mp3音乐文件
* @param key 键值
* @return 歌曲信息
* @throws Exception 可能抛出空指针异常
*/
private static String getInfoFromFrameMap(MP3File mp3File, String key) throws Exception {
ID3v23Frame frame = (ID3v23Frame) mp3File.getID3v2Tag().frameMap.get(key);
return frame.getContent();
}
}
MP3文件本身是自带音乐相关的信息比如,歌名,歌手,专辑等。
我们需要的信息在ID3v1或ID3v2的标签位置。
这里我们需要用到的jaudiotagger-2.2.6-SNAPSHOT.jar这个包
这里将读取的信息存放到music对象中去,然后返回这个对象。
private Music getSongInfo(String filePath) {
Music music = null;
try {
MP3File mp3File = (MP3File) AudioFileIO.read(new File(filePath));
MP3AudioHeader audioHeader = (MP3AudioHeader) mp3File.getAudioHeader();
ID3v1Tag tag = mp3File.getID3v1Tag();//获取ID3v1的信息
String songname = String.valueOf(tag.getTitle());//歌名
String artist = String.valueOf(tag.getArtist());//歌手
String album = String.valueOf(tag.getAlbum());//专辑
int duration = audioHeader.getTrackLength();//时长
//封装到music对象
music = new Music(songname, artist, album, duration, filePath);
} catch (Exception e) {
e.printStackTrace();
System.out.println("文件读取失败!"+e);
}
return music;
}
music类:
package model;
public class Music {
private int id;//音乐编号
private String name;//音乐名
private String singer;//歌手名
private String album;//专辑名
private int duration;//时长,以秒为单位
private String path;//音乐文件存放路径
/*
无参构造器
*/
public Music(){
}
public Music(String name, String singer, String album, int duration, String path) {
this.name = name;
this.singer = singer;
this.album = album;
this.duration = duration;
this.path = path;
}
public Music(int id, String name, String singer, String album, int duration,
String path) {
this.id = id;
this.name = name;
this.singer = singer;
this.album = album;
this.duration = duration;
this.path = path;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSinger() {
return singer;
}
public void setSinger(String singer) {
this.singer = singer;
}
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getAlbum() {
return album;
}
public void setAlbum(String album) {
this.album = album;
}
@Override
public String toString() {
return "Music{" +
"id=" + id +
", name='" + name + '\'' +
", singer='" + singer + '\'' +
", duration=" + duration +
", path='" + path + '\'' +
'}';
}
}
测试代码:
package test;
import model.Music;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.mp3.MP3AudioHeader;
import org.jaudiotagger.audio.mp3.MP3File;
import org.jaudiotagger.tag.id3.ID3v1Tag;
import java.io.File;
public class TestMP3 {
public static void main(String[] args) {
Music music = new TestMP3().getSongInfo(
"D:\\CloudMusic\\Alexandra Streliski - Le départ.mp3");
System.out.println(music.toString());
}
private Music getSongInfo(String filePath) {
Music music = null;
try {
MP3File mp3File = (MP3File) AudioFileIO.read(new File(filePath));
MP3AudioHeader audioHeader = (MP3AudioHeader) mp3File.getAudioHeader();
ID3v1Tag tag = mp3File.getID3v1Tag();
String songname = String.valueOf(tag.getTitle());//歌名
String artist = String.valueOf(tag.getArtist());//歌手
String album = String.valueOf(tag.getAlbum());//专辑
int duration = audioHeader.getTrackLength();//时长
music = new Music(songname, artist, album, duration, filePath);
} catch (Exception e) {
e.printStackTrace();
}
return music;
}
}
实验结果:
在运行上述代码后发现,基本上中文歌曲的歌名和歌手名会为空。
下列的代码对刚刚发现的bug,进行了修改,经过测试可以正常运行。
public Music getSongInfo(String filePath) {
Music music = null;
try {
MP3File mp3File = (MP3File) AudioFileIO.read(new File(filePath));
MP3AudioHeader audioHeader = (MP3AudioHeader) mp3File.getAudioHeader();
String songname = mp3File.getID3v2Tag().frameMap.get("TIT2").toString();//歌名
String artist = mp3File.getID3v2Tag().frameMap.get("TPE1").toString();//歌手
String album = mp3File.getID3v2Tag().frameMap.get("TALB").toString();//专辑
int duration = audioHeader.getTrackLength();//时长
music = new Music(reg(songname), reg(artist), reg(album), duration, filePath);
} catch (Exception e) {
e.printStackTrace();
}
return music;
}
测试发现songname,artist,album等,字符串会变成了“text = xxxx "
通过reg()函数处理了可以去掉。
//去除不必要的字符串
private String reg(String input) {
return input.substring(input.indexOf('"') + 1, input.lastIndexOf('"'));
}
ps:如有疑问,可以通过留言,向我提问,我们共同学习。
学习资料https://www.bilibili.com/video/BV1CJ411m7Gc?p=6问题的抛出出现的问题:海量用户高并发罪魁祸首——关系型数据库:性能瓶颈:磁盘IO性能低下扩展瓶颈:数据关系复杂,扩展性差,不便于大规模集群解决思路降低磁盘IO次数,越低越好 —— 内存存储去除数据间的关系,越简单越好 —— 不存储关系,仅存储数据Nosql简介NoSQL:即Not-OnlySQL(泛指非关系型的数据库),作为关系型数据库的补充。作用:应用对于海量用_redis入门基本操作
近期 整理了关于运放噪声的一些理论与计算方法,如下:1、热噪声电压计算公式 由于运动幅度会随着温度的上升而上升,热噪声的幅度也会跟随温度上升,热噪声均方根RMS(root meam square),可以表示如下: (1)其中:en 表示RMS噪声电压 ..._热噪声计算公式
问题描述:LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 1.单击菜单栏中的项目-属性。 2.点击配置属性,清单工具,输入输出,嵌入式菜单,将是改成否,点击确定保存。 3.重新调试。...
在Linux下查看磁盘空间使用情况,最常使用的就是du和df了。然而两者还是有很大区别的,有时候其输出结果甚至非常悬殊。1. 如何记忆这两个命令du -Disk Usagedf -Disk Free2. df 和du 的工作原理2.1 du的工作原理du命令会对待统计文件逐个调用fstat这个系统调用,获取文件大小。它的数据是基于文件获取的,所以有很大的灵活性,不一定非要针对一个分区,可以...
如何给RSU配路网一、路网数据采集:利用车载单元OBU的GPS定位模块在特定的路段,选取两个点,一个设定为起点,一个终点(一般大概300~400米左右)中间不能有实体将RSU的信号遮挡。配置的时候,将定位模块放在车顶最中间的位置,车停在道路中间,(下车查看,GPS定位模块大致和路的中心线在一条直线上。)在obu的home目录下输入gpsmon命令,可以读出GPS数据。..._金溢rsu
How To Create a SSL Certificate on nginx for CentOS 6TAGGED IN: NGINX, CENT OSAbout Self-Signed CertificatesA SSL certificate is a way to encrypt a site's information and create a more s
package com.lmt.until;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSession;import org.apache.ibatis.session.SqlSessionFactory;import org.apache.ibatis.session.SqlSessionFactoryBuilder;import javax.annotation.Resource;im
【官方】安卓团队正式介绍 Android RustAndroid平台提供了对用Rust开发本地操作系统组件的支持。Android Rust 模块 :https://source.andro...
egrep = grep -E 可以使用基本的正则表达外, 还可以用扩展表达式. 注意区别.扩展表达式:+ 匹配一个或者多个先前的字符, 至少一个先前字符.? 匹配0个或者多个先前字符.a|b|c 匹配a或b或c() 字符组, 如: love(able|ers) 匹配loveable或lovers.(..)(..)\1\2 模板匹配. \1代表前面第一个模板, \2代_egrep |sort
json和xml都是跨平台的解析语言,但是json相对于xml虽然可读性要差点但是其解析方式相对简单,有效数据多的特点广泛运用于安卓网络响应格式,而且安卓内部集成了json不需要再导入jar包,1.json格式1.1{“fistname”{“fistname”:"Brett",“Lastname”:"li"} 这是一个jsonObject,即整个{},其中包含的数据是以 键:值的方式存储的_json_array是全表扫吗
File->Reload as encoding…选择UTF-8Option->preference->Files->Default encoding选择Chinese GB18030 CP54936解决欢迎使用Markdown编辑器你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。新的改变我们对Markdown编辑器进行了一些功能拓展与语法支持,除了
目录1. 快捷键2. 基本语法2.1 字体设置斜体、粗体、删除线2.2 分级标题2.3 链接2.4 分割线2.5 代码块2.6 引用2.7 列表2.8 表格3. 常用技巧3.1 换行3.2 缩进字符3.3 特殊符号3.4 字体、字号与颜色3.5 链接的高级操作1.行内式2.参考式链接3.内容目录..._markwodn 语法