在Android上的MP3文件中精确查找 [英] Precise seek in MP3 files on Android

查看:200
本文介绍了在Android上的MP3文件中精确查找的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个应用程序,在该应用程序中准确搜索MP3文件非常重要.

I'm building an app where it's important to have accurate seeking in MP3 files.

当前,我以以下方式使用ExoPlayer:

Currently, I'm using ExoPlayer in the following manner:

public void playPeriod(long startPositionMs, long endPositionMs) {

    MediaSource mediaSource = new ClippingMediaSource(
            new ExtractorMediaSource.Factory(mDataSourceFactory).createMediaSource(mFileUri),
            startPositionMs * 1000,
            endPositionMs * 1000
    );

    mExoPlayer.prepare(mediaSource);
    mExoPlayer.setPlayWhenReady(true);

}

在某些情况下,这种方法会导致相对于预期播放时间的1-3秒偏移.

In some cases, this approach results in offsets of 1-3 seconds relative to the expected playback times.

我在ExoPlayer的github 上发现了此问题.看起来这是Mp3格式的ExoPlayer的固有限制,不会被修复.

I found this issue on ExoPlayer's github. Looks like this is an intrinsic limitation of ExoPlayer with Mp3 format and it won't be fixed.

我也找到了这个问题,这似乎暗示了Android的本地MadiaPlayer和MediaExtractor中存在相同的问题.

I also found this question which seems to suggest that the same issue exists in Android's native MadiaPlayer and MediaExtractor.

有没有一种方法可以在Android上的本地(例如设备上)Mp3文件中执行精确查找?我非常乐意接受任何破解或解决方法.

Is there a way to perform accurate seek in local (e.g. on-device) Mp3 files on Android? I'm more than willing to take any hack or workaround.

推荐答案

MP3文件本身并不是可搜索的.它们不包含任何时间戳.这只是一系列的MPEG帧,一个接一个.这使这个棘手.寻找MP3的方法有两种,每种方法都需要权衡.

MP3 files are not inherently seekable. They don't contain any timestamps. It's just a series of MPEG frames, one after the other. That makes this tricky. There are two methods for seeking an MP3, each with some tradeoffs.

最常见(也是最快)的方法是从第一个帧头读取比特率(或者从前几个帧头读取平均比特率),也许是128k.然后,取整个文件的字节长度,将其除以该比特率即可估算出文件的时间长度.然后,让用户搜索文件.如果他们将1:00放入2:00文件中,则将文件的字节大小除以50%的标记,然后将"needle drop"放入流中.读取文件,直到到达下一个帧头的同步字为止,然后开始解码.

The most common (and fastest) method is to read the bitrate from the first frame header (or, maybe the average bitrate from the first few frame headers), perhaps 128k. Then, take the byte length of the entire file, divide it by this bitrate to estimate the time length of the file. Then, let the user seek into the file. If they seek 1:00 into a 2:00 file, divide the byte size of the file to the 50% mark and "needle drop" into the stream. Read the file until a sync word for the next frame header comes by, and then begin decoding.

您可以想象,这种方法不准确.充其量,您将平均处于目标的半帧以内.帧大小为576个样本,这非常准确.但是,首先需要计算落针点.最常见的问题是ID3标签等会增加文件的大小,从而影响大小计算.一个更严重的问题是可变比特率(VBR)文件.如果您使用VBR编码音乐,并且曲目的开头是无声的或易于编码,则开头可能是32 kbps,而一秒钟可能是320 kbps.计算文件时间长度时出现10倍的错误!

As you can imagine, this method isn't accurate. At best, you're going to be within a half frame of the target on-average. With frame sizes being 576 samples, this is pretty accurate. However, there are problems with calculating the needle drop point in the first place. The most common issue is that ID3 tags and such add size to the file, throwing off the size calculations. A more severe issue is a variable bitrate (VBR) file. If you have music encoded with VBR, and the beginning of the track is silent-ish or otherwise easy to encode, the beginning might be 32 kbps whereas one second in might be 320 kbps. A 10x error in calculating the time length of the file!

第二种方法是将整个文件解码为原始PCM样本.这意味着您可以保证样本精确的寻道,但是您必须必须至少解码到寻道点.如果您想为整个曲目设置适当的时间长度,则必须 解码整个文件.大约20年前,这非常缓慢.聆听音轨几乎要花费聆听音轨所需的时间!如今,对于短文件,您可能可以将它们解码得如此之快,以至于没什么大不了的.

The second method is to decode the whole file to raw PCM samples. This means you can guarantee sample-accurate seeking, but you must decode at least up to the seek point. If you want a proper time length for the full track, you must decode the whole file. Some 20 years ago, this was painfully slow. Seeking into a track would take almost as long as listening to the track to the point you were seeking to! These days, for short files, you can probably decode them so fast that it doesn't matter so much.

TL; DR;如果必须进行精确样本的搜索,请先对文件进行解码,然后再将其放入播放器中,但在决定此折衷方案之前,请先了解性能损失.

TL;DR; If you must have sample-accurate seeking, decode the files first before putting them in your player, but understand the performance penalty first before deciding this tradeoff.

这篇关于在Android上的MP3文件中精确查找的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆