Как получить синхронизированные файлы из Firebase в Android? - PullRequest
0 голосов
/ 04 июня 2018

Я пытаюсь сделать приложение, которое работает с аудио файлами.Я должен импортировать и объединять аудиофайлы из 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, но в этом случае я не смогу полностью подготовить массивы к использованию.

Я использую этот пост для объединения.

1 Ответ

0 голосов
/ 04 июня 2018

В вашем коде много чего происходит, поэтому я сосредоточусь только на одной его части.

Проблема вызвана тем, что 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());
        }
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...