我正在尝试创建一个适用于音频文件的应用程序。我必须在应用程序的一部分中从Firebase导入和合并音频文件。
以下是合并操作的代码块;
protected void combine() {
String randomFileName = String.valueOf(System.currentTimeMillis());
lastRecordedFilePath = Environment.getExternalStorageDirectory() + "/MueasycoCombinedAudios/" + randomFileName + ".wav";
lastRecordedFileName = randomFileName + ".wav";
File folder = new File(Environment.getExternalStorageDirectory() + "/MueasycoCombinedAudios");
File folder1 = new File(Environment.getExternalStorageDirectory() + "/MueasycoDownloadedAudios");
if (!folder.exists()) {
folder.mkdirs();
}
if (!folder1.exists()) {
folder1.mkdirs();
}
int counter = 0;
int counter1 = 0;
int counter2 = 0;
try {
DataOutputStream amplifyOutputStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(Environment.getExternalStorageDirectory() + "/MueasycoCombinedAudios/" + randomFileName + ".wav")));
DataInputStream[] mergeFilesStream = new DataInputStream[trackList.size()];
long[] sizes = new long[trackList.size()];
for (Iterator<TrackModel> i = trackList.iterator(); i.hasNext(); ) {
TrackModel item = i.next();
final StorageReference fileReference = mStorageRef.child("AudioRecords/" + item.fileName);
final File file = new File(Environment.getExternalStorageDirectory() + "/MueasycoDownloadedAudios/" + item.fileName);
fileReference.getFile(file).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
@Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
Log.e("firebase ", ";local tem file created created " + file.toString());
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Handle any errors
}
});
sizes[counter] = (file.length() - 44) / 2;
counter++;
}
for (Iterator<TrackModel> i = trackList.iterator(); i.hasNext(); ) {
TrackModel item = i.next();
while (true) {
File control = new File(Environment.getExternalStorageDirectory() + "/MueasycoDownloadedAudios/" + item.fileName);
if (control.exists()) {
mergeFilesStream[counter1] = new DataInputStream(new BufferedInputStream(new FileInputStream(Environment.getExternalStorageDirectory() + "/MueasycoDownloadedAudios/" + item.fileName)));
break;
} else {
Log.e("mueasyco ", "Dosya yok" + control.getName());
}
}
if (counter1 == trackList.size() - 1) {
mergeFilesStream[counter1].skip(24);
byte[] sampleRt = new byte[4];
mergeFilesStream[counter1].read(sampleRt);
ByteBuffer bbInt = ByteBuffer.wrap(sampleRt).order(ByteOrder.LITTLE_ENDIAN);
RECORDER_SAMPLERATE = bbInt.getInt();
mergeFilesStream[counter1].skip(16);
} else {
mergeFilesStream[counter1].skip(44);
}
counter1++;
}
for (Iterator<TrackModel> i = trackList.iterator(); i.hasNext(); ) {
TrackModel item = i.next();
final StorageReference fileReference = mStorageRef.child("AudioRecords/" + item.fileName);
for (int a = 0; a < (int) sizes[counter2]; counter2++) {
byte[] dataBytes = new byte[2];
try {
dataBytes[0] = mergeFilesStream[counter2].readByte();
dataBytes[1] = mergeFilesStream[counter2].readByte();
} catch (EOFException e) {
amplifyOutputStream.close();
}
short dataInShort = ByteBuffer.wrap(dataBytes).order(ByteOrder.LITTLE_ENDIAN).getShort();
float dataInFloat = (float) dataInShort / 37268.0f;
short outputSample = (short) (dataInFloat * 37268.0f);
byte[] dataFin = new byte[2];
dataFin[0] = (byte) (outputSample & 0xff);
dataFin[1] = (byte) ((outputSample >> 8) & 0xff);
amplifyOutputStream.write(dataFin, 0, 2);
}
counter2++;
}
amplifyOutputStream.close();
for (int a = 0; a < trackList.size(); a++) {
mergeFilesStream[a].close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
long size = 0;
try {
FileInputStream fileSize = new FileInputStream(Environment.getExternalStorageDirectory() + "/MueasycoCombinedAudios/" + randomFileName + ".wav");
size = fileSize.getChannel().size();
fileSize.close();
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
final int RECORDER_BPP = 16;
long datasize = size + 36;
long byteRate = (RECORDER_BPP * RECORDER_SAMPLERATE) / 8;
long longSampleRate = RECORDER_SAMPLERATE;
byte[] header = new byte[44];
header[0] = 'R'; // RIFF/WAVE header
header[1] = 'I';
header[2] = 'F';
header[3] = 'F';
header[4] = (byte) (datasize & 0xff);
header[5] = (byte) ((datasize >> 8) & 0xff);
header[6] = (byte) ((datasize >> 16) & 0xff);
header[7] = (byte) ((datasize >> 24) & 0xff);
header[8] = 'W';
header[9] = 'A';
header[10] = 'V';
header[11] = 'E';
header[12] = 'f'; // 'fmt ' chunk
header[13] = 'm';
header[14] = 't';
header[15] = ' ';
header[16] = 16; // 4 bytes: size of 'fmt ' chunk
header[17] = 0;
header[18] = 0;
header[19] = 0;
header[20] = 1; // format = 1
header[21] = 0;
header[22] = (byte) 1;
header[23] = 0;
header[24] = (byte) (longSampleRate & 0xff);
header[25] = (byte) ((longSampleRate >> 8) & 0xff);
header[26] = (byte) ((longSampleRate >> 16) & 0xff);
header[27] = (byte) ((longSampleRate >> 24) & 0xff);
header[28] = (byte) (byteRate & 0xff);
header[29] = (byte) ((byteRate >> 8) & 0xff);
header[30] = (byte) ((byteRate >> 16) & 0xff);
header[31] = (byte) ((byteRate >> 24) & 0xff);
header[32] = (byte) ((RECORDER_BPP) / 8); // block align
header[33] = 0;
header[34] = RECORDER_BPP; // bits per sample
header[35] = 0;
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
header[40] = (byte) (size & 0xff);
header[41] = (byte) ((size >> 8) & 0xff);
header[42] = (byte) ((size >> 16) & 0xff);
header[43] = (byte) ((size >> 24) & 0xff);
try {
RandomAccessFile rFile = new RandomAccessFile(Environment.getExternalStorageDirectory() + "/MueasycoCombinedAudios/" + randomFileName + ".wav", "rw");
rFile.seek(0);
rFile.write(header);
rFile.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
uploadFile();
}
问题是下载firebase文件的代码继续有效。正如您所看到的,我尝试使用无限循环修复此问题,但Firebase在未正确加载时会创建文件,因此解决方案不成功。
fileReference.getFile(file).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
@Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
Log.e("firebase ", ";local tem file created created " + file.toString());
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Handle any errors
}
});
我尝试编写我为加入onSuccess事件而创建的数组,但在这种情况下,我将无法完全准备要使用的数组。
我正在使用this post进行合并。
答案 0 :(得分:1)
您的代码中有很多内容,所以我只关注其中的一部分。
问题是由Firebase异步从服务器下载文件引起的。在下载文件时,它会继续运行您的代码,而不是阻止您的代码。因此,如果您不考虑此异步行为,则在实际下载数据之前,您将合并这些文件。
查看发生了什么的最简单方法是使用一些日志语句:
Log.i("Firebase", "Starting downloading from storage");
fileReference.getFile(file).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
@Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
Log.i("Firebase", "Download done");
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
Log.e("Firebase", "Download failed: "+exception.toString());
}
});
Log.i("Firebase", "After starting download from storage");
如果您运行此代码,您将获得:
开始从存储空间下载
从存储开始下载后
下载完成
这可能不是您所期望的,但完美地解释了为什么您的合并代码失败:它想要合并的数据尚不可用。
解决方案是更改调用代码的顺序。下载完文件后,检查这是否是最终文件。如果是,请开始合并:
for (Iterator<TrackModel> i = trackList.iterator(); i.hasNext(); ) {
TrackModel item = i.next();
final StorageReference fileReference = mStorageRef.child("AudioRecords/" + item.fileName);
final File file = new File(Environment.getExternalStorageDirectory() + "/MueasycoDownloadedAudios/" + item.fileName);
fileReference.getFile(file).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
@Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
sizes[counter] = (file.length() - 44) / 2;
counter++;
if (counter == trackList.size()) {
Log.i("Firebase", "Downloads completed");
// TODO: merge the downloaded files here
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
Log.e("Firebase", "Download failed: "+exception.toString());
}
});
}