我们的应用程序有很多类似音乐的音频,因为我们有搜索栏,播放/暂停控制等等。
我们遇到的问题是,在某些设备上,我们无法使用搜索栏来寻找文件的开头,而不会在开始时(或大约一秒钟,给予或接受)时出现口吃或丢失少量文件。从文件到文件和设备到设备的跳过量不同,但每次使用相同的文件 - 设备组合时数量相同。
我们可以从头开始没有这些问题的唯一方法是调用MediaPlayer.stop()
,然后重新开始发布和构建 - 我们想要避免的事情,因为应该正常工作。寻求文件的其他区域似乎是有效的,或者至少它不是那么明显。
这种情况发生在我们的大多数设备上,经过测试的型号包括华硕Nexus 7,华为Nexus 6P,LG G4和索尼Xperia Z.值得注意的是,我们没有在我们的设备上体验过这一点。三星片。
我们使用JNI在C ++中进行编码,至少使用Android 4.4。因此,我们所有的MediaPlayer调用都通过JNI进入java代码。搜索栏以百分比形式传递介于0和1之间的值,我们已确认它确实向JNI发送了0。
有问题的文件是立体声Ogg Vorbis,可变比特率采样频率为44.1 KHz。它们存储在OBB(打包为未压缩的zip)中,可通过具有偏移量和长度的FileInputStream访问。我们在应用程序的其他区域成功地使用此方法(或C ++方面的类似方法)来处理纹理或XML文件等其他文件。如果需要,我们确实在使用之前复制文件;但是,如果可以,我们宁愿避免这种情况。
我们做错了吗?这是一个已知的问题吗?有解决方法吗?
public void JNI_Audio_StartTrack(int iTrackIndex, String audioPath, long offset, long length)
{
if (enableDebug)
{
String myString = String.format("ExtAudio_StartTrack(%d,%s,%d,%d)", iTrackIndex, audioPath, offset, length);
Log.d("Tag", myString);
}
if (mediaPlayerInited)
{
mediaPlayer.release();
}
Context context = getApplicationContext();
int trackResource = 0;
FileInputStream fis = null;
try
{
fis = new FileInputStream(audioPath);
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(fis.getFD(), offset, length);
mediaPlayer.prepare();
mediaPlayer.start();
mediaPlayerInited = true;
}
//Normal FileInputStream handling Catch...Finally blocks follow
}
public void JNI_Audio_SeekTo(float iPercentage)
{
if (enableDebug)
{
String myString = String.format("ExtAudio_SeekTo(%f)", iPercentage);
Log.d("Tag", myString);
}
if (mediaPlayerInited)
{
int duration = mediaPlayer.getDuration();
float newSeekPos = (float)duration * iPercentage;
mediaPlayer.seekTo((int)newSeekPos);
}
}