java - 是否有可能以某种方式将 .setMicrosecondPosition() 与线一起使用,还是只能与剪辑一起使用
问题描述
我目前正在制作 mp3 播放器,NetBeans 12.1
但找不到控制歌曲当前位置的方法。
我试过使用.setMicrosecondPosition()
,但它似乎只适用于剪辑而不适用于线。我的播放器甚至可以更改曲目的当前位置还是我应该更改我的代码?
这是播放器的代码。
public void run() {
final File file = new File(filePath);
try (final AudioInputStream in = AudioSystem.getAudioInputStream(file)) {
final AudioFormat outFormat = getOutFormat(in.getFormat());
final Info info = new Info(SourceDataLine.class, outFormat);
try (final SourceDataLine line
= (SourceDataLine) AudioSystem.getLine(info)) {
getLine(line);
line.getMicrosecondPosition();
if (line != null) {
line.open(outFormat);
line.start();
long millis;
AudioFileFormat fileFormat = AudioSystem.getAudioFileFormat(file);
Map<?, ?> properties = ((TAudioFileFormat) fileFormat).properties();
String key = "duration";
String title = "title";
Long microseconds = (Long) properties.get(key);
maksimumSekunde = (int)TimeUnit.MICROSECONDS.toSeconds(microseconds);
title1 = (String) properties.get(title);
int mili = (int) (microseconds / 1000);
sec = (mili / 1000) % 60;
min = (mili / 1000) / 60;
setVolumeDown(sliderGlasnoca.getValue());
//STREAM
int n = 0;
final byte[] buffer = new byte[4096];
AudioInputStream inp = getAudioInputStream(outFormat, in);
while (n != -1) {
if (pauza == true) {
break;
}
if (stop == true) {
synchronized (LOCK) {
LOCK.wait();
}
}
n = inp.read(buffer, 0, buffer.length);
if (n != -1) {
line.write(buffer, 0, n);
}
millis = TimeUnit.MICROSECONDS.toMillis(line.getMicrosecondPosition());
trajanjeSekunde = (int)TimeUnit.MICROSECONDS.toSeconds(line.getMicrosecondPosition());
minutes = (millis / 1000) / 60;
seconds = ((millis / 1000) % 60);
//System.out.println(minutes + ":" + seconds + " " + "time = " + min + ":" + sec + " " + title1);
}
//STREAM
line.drain();
line.stop();
Finished();
}
} catch (InterruptedException ex) {
}
} catch (UnsupportedAudioFileException
| LineUnavailableException
| IOException e) {
throw new IllegalStateException(e);
}
}
这是我第一次在这里发帖。
解决方案
我总是从通过 读取的字节中计数和丢弃帧AudioInputStream
,但重新审视 API,我发现可以使用该AudioInputStream.skip(...)
方法向前跳转给定数量的字节。计算对应于给定时间量的字节数涉及知道每帧的字节数,例如,16 位编码,立体声是每帧 4 字节,以及采样率。
IDK 如果一个人可以可靠地向后跳过。这将取决于是否可以“标记”和“重置” AudioInputStream
. 如果支持这些功能,似乎可以想象mark(...)
. AudioInputStream
然后,要向后退,首先reset()
回到起点,然后通过 向前跳skip(...)
。我没有测试过这个。很大程度上取决于mark(...)
方法中允许的字节数。
如果在播放音频的中间开始或停止,由于信号的不连续性,馈送到的数据SourceDataLine
可能会出现“咔哒”声。为了解决这个问题,可能需要将启动和停止转换为 PCM,并在启动时提高音量,或者在停止时降低音量。所需的帧数可能需要通过实验来确定。我猜 44100fps 的 64 帧可能是一个不错的第一次尝试。
推荐阅读
- python - 将 S3 中的 excel 文件读入 Pandas DataFrame
- firebase - 一段时间后,Firebase 消息传递失败
- unit-testing - CQRS 系统中的单元测试领域模型属性
- php - Google Charts - 来自外部文本文件的多系列动态折线图
- angularjs - angularjs引导选项卡在第一次动态后没有变化
- proxy - 为缓存代理设置 conda (MacOs + Squidman)
- hyperledger-fabric - 将 org3 添加到第一个网络示例后无法创建频道
- java - 关闭 ANTLR4 CharStream(Java 运行时) - OutOfMemoryException
- vb.net - 尝试加入两个结果集的 LINQ to Entities 中的错误
- node.js - 如何使用 facebook 登录或将 facebook 帐户链接到用户池中的当前用户