Android MediaExtractor readSampleData IllegalArgumentException
Android MediaExtractor readSampleData IllegalArgumentException
我试着按照这个问题Concatenate multiple mp4 audio files using android´s MediaMuxer 并连接视频文件。
但由于某些原因,当我调用 readSampleData
时,MediaExtractor 抛出 IllegalArgumentException
在官方API中,这个函数根本不应该抛出任何异常!怎么回事?
我发现一个老问题表明 ByteBuffer 的大小可能是问题所在:Android MediaMuxer readSampleData IllegalStateException
我已经尝试了很多大小值,其中 none 使问题消失了。有我应该知道的标准尺寸吗?
任何提示都有帮助!
boolean VERBOSE = true;
private boolean concatenateFiles(File dst, List<File> sources) {
if ((sources == null) || (sources.size() == 0)) {
return false;
}
boolean result;
MediaExtractor extractor = null;
MediaMuxer muxer = null;
try {
// Set up MediaMuxer for the destination.
muxer = new MediaMuxer(dst.getPath(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
// Copy the samples from MediaExtractor to MediaMuxer.
boolean sawEOS = false;
int frameCount = 0;
int offset = 100;
ByteBuffer dstBuf = ByteBuffer.allocate(256 * 1024);
BufferInfo bufferInfo = new BufferInfo();
long timeOffsetUs = 0;
int dstTrackIndex = -1;
for (int fileIndex = 0; fileIndex < sources.size(); fileIndex++) {
int numberOfSamplesInSource = getNumberOfSamples(sources.get(fileIndex));
if (VERBOSE) {
Log.d(TAG, String.format("Source file: %s", sources.get(fileIndex).getPath()));
}
if (!sources.get(fileIndex).canRead()) {
throw new FileNotFoundException("Unable to read " + sources.get(fileIndex));
}
// Set up MediaExtractor to read from the source.
extractor = new MediaExtractor();
extractor.setDataSource(sources.get(fileIndex).getPath());
// Set up the tracks.
SparseIntArray indexMap = new SparseIntArray(extractor.getTrackCount());
for (int i = 0; i < extractor.getTrackCount(); i++) {
extractor.selectTrack(i);
MediaFormat format = extractor.getTrackFormat(i);
if (dstTrackIndex < 0) {
dstTrackIndex = muxer.addTrack(format);
muxer.start();
}
indexMap.put(i, dstTrackIndex);
}
long lastPresentationTimeUs = 0;
int currentSample = 0;
while (!sawEOS) {
bufferInfo.offset = offset;
bufferInfo.size = extractor.readSampleData(dstBuf, offset);
if (bufferInfo.size < 0) {
sawEOS = true;
bufferInfo.size = 0;
timeOffsetUs += (lastPresentationTimeUs);
}
else {
lastPresentationTimeUs = extractor.getSampleTime();
bufferInfo.presentationTimeUs = extractor.getSampleTime() + timeOffsetUs;
bufferInfo.flags = extractor.getSampleFlags();
int trackIndex = extractor.getSampleTrackIndex();
if ((currentSample < numberOfSamplesInSource) || (fileIndex == sources.size() - 1)) {
muxer.writeSampleData(indexMap.get(trackIndex), dstBuf, bufferInfo);
}
extractor.advance();
frameCount++;
currentSample++;
if (VERBOSE) {
Log.d(TAG, "Frame (" + frameCount + ") " +
"PresentationTimeUs:" + bufferInfo.presentationTimeUs +
" Flags:" + bufferInfo.flags +
" TrackIndex:" + trackIndex +
" Size(KB) " + bufferInfo.size / 1024);
}
}
}
extractor.release();
extractor = null;
}
result = true;
}
catch (Exception e) {
e.printStackTrace();
result = false;
}
finally {
if (extractor != null) {
extractor.release();
}
if (muxer != null) {
muxer.stop();
muxer.release();
}
}
return result;
}
解码 4k 电影时出现此错误。其他人(包括其他非常高分辨率的电影)一直工作正常,但大约在中途-co-incedentilly 靠近更复杂的场景...- 我收到此错误。
我的缓冲区大小是 1mb (1024*1024),增加到 2mb,问题就解决了。
所以您在源代码中找到的 END_OF_STREAM 大概是 "end of the buffer"
我试着按照这个问题Concatenate multiple mp4 audio files using android´s MediaMuxer 并连接视频文件。
但由于某些原因,当我调用 readSampleData
时,MediaExtractor 抛出 IllegalArgumentException在官方API中,这个函数根本不应该抛出任何异常!怎么回事?
我发现一个老问题表明 ByteBuffer 的大小可能是问题所在:Android MediaMuxer readSampleData IllegalStateException
我已经尝试了很多大小值,其中 none 使问题消失了。有我应该知道的标准尺寸吗?
任何提示都有帮助!
boolean VERBOSE = true;
private boolean concatenateFiles(File dst, List<File> sources) {
if ((sources == null) || (sources.size() == 0)) {
return false;
}
boolean result;
MediaExtractor extractor = null;
MediaMuxer muxer = null;
try {
// Set up MediaMuxer for the destination.
muxer = new MediaMuxer(dst.getPath(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
// Copy the samples from MediaExtractor to MediaMuxer.
boolean sawEOS = false;
int frameCount = 0;
int offset = 100;
ByteBuffer dstBuf = ByteBuffer.allocate(256 * 1024);
BufferInfo bufferInfo = new BufferInfo();
long timeOffsetUs = 0;
int dstTrackIndex = -1;
for (int fileIndex = 0; fileIndex < sources.size(); fileIndex++) {
int numberOfSamplesInSource = getNumberOfSamples(sources.get(fileIndex));
if (VERBOSE) {
Log.d(TAG, String.format("Source file: %s", sources.get(fileIndex).getPath()));
}
if (!sources.get(fileIndex).canRead()) {
throw new FileNotFoundException("Unable to read " + sources.get(fileIndex));
}
// Set up MediaExtractor to read from the source.
extractor = new MediaExtractor();
extractor.setDataSource(sources.get(fileIndex).getPath());
// Set up the tracks.
SparseIntArray indexMap = new SparseIntArray(extractor.getTrackCount());
for (int i = 0; i < extractor.getTrackCount(); i++) {
extractor.selectTrack(i);
MediaFormat format = extractor.getTrackFormat(i);
if (dstTrackIndex < 0) {
dstTrackIndex = muxer.addTrack(format);
muxer.start();
}
indexMap.put(i, dstTrackIndex);
}
long lastPresentationTimeUs = 0;
int currentSample = 0;
while (!sawEOS) {
bufferInfo.offset = offset;
bufferInfo.size = extractor.readSampleData(dstBuf, offset);
if (bufferInfo.size < 0) {
sawEOS = true;
bufferInfo.size = 0;
timeOffsetUs += (lastPresentationTimeUs);
}
else {
lastPresentationTimeUs = extractor.getSampleTime();
bufferInfo.presentationTimeUs = extractor.getSampleTime() + timeOffsetUs;
bufferInfo.flags = extractor.getSampleFlags();
int trackIndex = extractor.getSampleTrackIndex();
if ((currentSample < numberOfSamplesInSource) || (fileIndex == sources.size() - 1)) {
muxer.writeSampleData(indexMap.get(trackIndex), dstBuf, bufferInfo);
}
extractor.advance();
frameCount++;
currentSample++;
if (VERBOSE) {
Log.d(TAG, "Frame (" + frameCount + ") " +
"PresentationTimeUs:" + bufferInfo.presentationTimeUs +
" Flags:" + bufferInfo.flags +
" TrackIndex:" + trackIndex +
" Size(KB) " + bufferInfo.size / 1024);
}
}
}
extractor.release();
extractor = null;
}
result = true;
}
catch (Exception e) {
e.printStackTrace();
result = false;
}
finally {
if (extractor != null) {
extractor.release();
}
if (muxer != null) {
muxer.stop();
muxer.release();
}
}
return result;
}
解码 4k 电影时出现此错误。其他人(包括其他非常高分辨率的电影)一直工作正常,但大约在中途-co-incedentilly 靠近更复杂的场景...- 我收到此错误。
我的缓冲区大小是 1mb (1024*1024),增加到 2mb,问题就解决了。
所以您在源代码中找到的 END_OF_STREAM 大概是 "end of the buffer"