如何在 Android 中从 Firebase 同步文件?

2024-02-17

我正在尝试制作一个可处理音频文件的应用程序。我必须在应用程序的一部分中从 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 事件而创建的数组,但在这种情况下,我将无法完全准备好要使用的数组。

我在用这个帖子 https://stackoverflow.com/questions/23112372/android-concat-2-audio-wav-or-mp3-files合并。


您的代码中有很多内容,因此我将只关注其中的一部分。

该问题是由于 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());
        }
    });
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Android 中从 Firebase 同步文件? 的相关文章

随机推荐