我需要将数据传递给MediaExtractor
,为此我使用此方法SetDataSource
https://developer.android.com/ndk/reference/group/media#amediaextractor_setdatasourcefd
像这样:
int32_t NDK_extractor::decode()
{
FILE *fp = nullptr;
media_status_t err;
AMediaExtractor *ex = AMediaExtractor_new();
fp = fopen("/storage/emulated/0/Android/data/com.test.debug/files/Models/test.mp3", "rb");
if (fp)
{
err = AMediaExtractor_setDataSourceFd(ex, fileno(fp), 0, dataSize);
}
else
{
LOGE("Failed open file");
return 0;
}
if (err != AMEDIA_OK)
{
LOGE("SOUND :: Error setting ex data source, err %d", err);
return 0;
}
...
}
它工作得很好,但现在我需要处理指向数据和数据大小的指针,所以我把这个方法改成了
int32_t NDK_extractor::decode()
{
FILE *fp = nullptr;
media_status_t err;
AMediaExtractor *ex = AMediaExtractor_new();
fp = fopen("/storage/emulated/0/Android/data/com.test.debug/files/Models/test.mp3", "rb");
fseek(fp, 0, SEEK_END);
long lSize = ftell(fp);
rewind(fp);
void *buf = new unsigned char[lSize];
fread(buf, 1, lSize, fp);
fclose(fp);
fp = fmemopen(buf, lSize, "r");
if (fp)
{
err = AMediaExtractor_setDataSourceFd(ex, fileno(fp), 0, dataSize);
}
else
{
LOGE("Failed open file");
return 0;
}
if (err != AMEDIA_OK)
{
LOGE("SOUND :: Error setting ex data source, err %d", err);
return 0;
}
...
}
因此,我在缓冲区中读取相同的数据(如前一个例子(,也得到了一个大小,然后我用fmemopen
打开它,结果得到了这样一个错误-AMEDIA_error_BASE
这里有什么问题?为什么它在一种情况下有效,而在另一种情况中无效,尽管它几乎是一样的?我错过了什么?
因此,问题是AMediaExtractor_setDataSourceFd
方法接受文件描述符作为参数。为了从FILE
获得文件描述符,您需要在用fopen()
打开的FILE
上调用fileno()
方法,然后一切都很好,但如果用fmemopen()
打开文件,则fileno()
返回-1。我试着用管子做https://stackoverflow.com/a/1559018/5709159,但这种方法对AMediaExtractor_setDataSourceFd
不起作用(我认为因为管道不支持seek(((试图通过自定义MediaExtractor
(方法setDataSource((之一(来实现,但它只是用api 29引入的(它不太适合我(,最后我用了一个变通方法来实现-我得到了字节,写入一个临时文件,用fopen()
打开这个文件,然后调用fileno()
获取文件描述符并将其传递给setDataSouceFd()