又研究了一番,找了大概的问题:
(1)我把不能播放的MP3用格式工厂降低比特率,原来281K的减少到71K,可以播
(2)但大的MP3减少了还是有问题
(3)仿佛和文件大小有关
(4)看了错误的-2147483648,这是int的最大值,感觉可能是引擎的哪里以一个int值来计算什么,当文件过大时,超过int,会说offset有问题,
(5)urlaudioplayer cpp,其实C++不会
bool UrlAudioPlayer::prepare(const std::string &url, SLuint32 locatorType, std::shared_ptr assetFd, int start,
int length)
{
_url = url;
_assetFd = assetFd;
ALOGV("UrlAudioPlayer::prepare: %s, %d, %d, %d, %d", _url.c_str(), (int)locatorType, assetFd->getFd(), start,
length);
SLDataSource audioSrc;
SLDataFormat_MIME formatMime = {SL_DATAFORMAT_MIME, nullptr, SL_CONTAINERTYPE_UNSPECIFIED};
audioSrc.pFormat = &formatMime;
//Note: locFd & locUri should be outside of the following if/else block
// Although locFd & locUri are only used inside if/else block, its lifecycle
// will be destroyed right after '}' block. And since we pass a pointer to
// 'audioSrc.pLocator=&locFd/&locUri', pLocator will point to an invalid address
// while invoking Engine::createAudioPlayer interface. So be care of change the position
// of these two variables.
SLDataLocator_AndroidFD locFd;
(6)再往上找,发现,previder中
Check audio file size to determine to use a PcmAudioService or UrlAudioPlayer,
也就是说小的当成是音效,用的pcmaudio ,这部分确可以播,logcat的结果也是这样,
大的用UrlAudioPlayer来播
(7)再往上
AudioPlayerProvider::AudioFileInfo AudioPlayerProvider::getFileInfo(
const std::string &audioFilePath)
{
AudioFileInfo info;
long fileSize = 0;
貌似 fileSize是long型的
而bool ret = urlPlayer->prepare(info.url, locatorType, info.assetFd, info.start, info.length);时
那边变成int了
大大们不喜勿喷
(7)改了之后还是不对,估计和locatorType有关,再看看
(8)改好了,是BUG,但最后的修改还是要引擎大大们再改,我用了一个临时的方案
在urlaudioplay.cpp中295行左右改成了这样
if (locatorType == SL_DATALOCATOR_ANDROIDFD)
{
locFd = {locatorType, _assetFd->getFd(), start, length};
audioSrc.pLocator = &locFd;
ALOGV(“locFd: locatorType: %d”, (int)locFd.locatorType);
if(_url[0]==’/’){
locUri = {SL_DATALOCATOR_URI, (SLchar *) _url.c_str()};
audioSrc.pLocator = &locUri;
ALOGV(“locUri: locatorType: %d”, (int)locUri.locatorType);
}
}
应该是provider中的472行
SLuint32 locatorType = info.assetFd > 0 ? SL_DATALOCATOR_ANDROIDFD : SL_DATALOCATOR_URI;
使发过来的 locatorType总是 SL_DATALOCATOR_ANDROIDFD而不是SL_DATALOCATOR_URI,我只好在里面再判断一次,但C++真是不会,那个makeshare什么的,不知道什么意思,只好改在这里了。
完了可以播了。
呼叫引擎大大们吧。
看到最新的引擎已经改了
SLuint32 locatorType = info.assetFd->getFd() > 0 ? SL_DATALOCATOR_ANDROIDFD : SL_DATALOCATOR_URI;