由于amr文件在java中不能直接播放,不然响一声直接过去了,需要转为mp3或者wav,这里使用了wav方式,
由于需要对播放进行控制,同一时间只能有一个声音,并且播放中需要自定义是否打断,这个是搭配其它逻辑进行的,所以这里只给出将amr文件转wav然后播放的逻辑,如果需要一种业务场景是,多条语音顺序广播及紧急口播播放(最紧急,可终止当前声音播放)的话,可以移步到我下一个文章查看。
import it.sauronsoftware.jave.AudioAttributes;
import it.sauronsoftware.jave.Encoder;
import it.sauronsoftware.jave.EncoderException;
import it.sauronsoftware.jave.EncodingAttributes;
import it.sauronsoftware.jave.InputFormatException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.ObjectMapper;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
/*
* 播放wav文件,这里是我下一篇文章的部分内容
*/
public class ReadWav {
private FileInputStream fileau = null;
private String stop_date = getNowTime(); //文件播放的结束时间,初始为当前时间
private static String talk_name = "talking.wav"; //播放的文件名称
private static String loop_num = "2"; //默认循环
private static boolean is_replace = false; //是否下次语音覆盖正在播放的语音
//可以从配置文件中读取
static{
try {
Properties pro = PropertiesUtil.getProperties("Config.properties");
allWav_name = pro.getProperty("talk_name");
loop_num = pro.getProperty("loop_num");
is_replace = Boolean.parseBoolean(pro.getProperty("is_replace"));
} catch (Exception e) {
e.printStackTrace();
}
}
//停止语音播放
public void stopWav() throws Exception{
AudioPlayer.player.stop(fileau);
stop_date = getNowTime() ; //将结束控制日期改为当前
}
//播放
public void playVideo(String filePath,String duration) throws Exception{
//如果在停止播放时间之前再次播放,则直接返回不播放
if(compare_date(getNowTime(),stop_date) == -1){
return ;
}
//是否覆盖播放,如果不覆盖,则同时有两个声音出现
if(is_replace){
AudioPlayer.player.stop(fileau); // 这个是停止正在播放的
}
changeToWav(filePath,talk_name,new Float(duration)); //将amr转为wav
fileau = new FileInputStream(talk_name); //播放的语音流
long wav_time = CalculationTime(talk_name)*1000+10; //文件时长,+10毫秒是为了保险点
stop_date = getDateByAdd((int)wav_time); //文件播放完的日期
AudioPlayer.player.start(fileau); //播放
}
/**
*
* @Title: changeToWav
* @Description: TODO(将语音文件转为wav格式)
* @param @param sourcePath
* @param @param targetPath 参数
* @return void 返回类型
* @throws
*/
public static void changeToWav(String sourcePath, String targetPath,Float duration) {
try {
File source = new File(sourcePath);
File target = new File(targetPath);
AudioAttributes audio = new AudioAttributes();
Encoder encoder = new Encoder();
//设置解码格式,比特率,位数,声道等信息
audio.setCodec("pcm_s16le");
audio.setBitRate(new Integer(705000));
audio.setChannels(new Integer(1));
audio.setSamplingRate(new Integer(44100));
audio.setVolume(new Integer(500));
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("wav");
attrs.setAudioAttributes(audio);
attrs.setDuration(duration);
encoder.encode(source, target, attrs);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InputFormatException e) {
e.printStackTrace();
} catch (EncoderException e) {
e.printStackTrace();
}
}
//计算WAV文件时间
public static long CalculationTime(String adress) throws LineUnavailableException,
UnsupportedAudioFileException, IOException{
File file = new File(adress);
Clip clip = AudioSystem.getClip();
AudioInputStream ais = AudioSystem.getAudioInputStream(file);
clip.open(ais);
long times = (long) (clip.getMicrosecondLength() / 1000000D);
return times;
}
//获取当前时间+给定秒之后的时间
public static String getDateByAdd(long s){
long currentTime = System.currentTimeMillis() ;
currentTime += s;
Date date = new Date(currentTime);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateStr = sdf.format(date);
return dateStr ;
}
/**
*
* @Title: compare_date
* @Description: TODO(比较日期大小)
* @param @param DATE1
* @param @param DATE2
* @param @return 参数
* @return int 返回类型
* @throws
*/
public static int compare_date(String DATE1, String DATE2) {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date dt1 = df.parse(DATE1);
Date dt2 = df.parse(DATE2);
if (dt1.getTime() > dt2.getTime()) {
return 1 ;
} else if (dt1.getTime() < dt2.getTime()) {
return -1 ;
} else {
return 0;
}
} catch (Exception exception) {
exception.printStackTrace();
}
return 0;
}
/**
*
* @Title: getNowTime
* @Description: TODO(获取当前时间)
* @param @return 参数
* @return String 返回类型
* @throws
*/
public static String getNowTime(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String now = sdf.format(new Date()) ;
return now ;
}
}