Как сохранить входной поток байтового массива в виде файла .wav в хранилище s3

В моем приложении scala я вызываю службу хранения s3 для загрузки моего входного потока массива байтов. Я хочу, чтобы этот входной поток сохранялся в виде файла .wav. Код приведен ниже

val bytes1 = new sun.misc.BASE64Decoder().decodeBuffer(base64String)
var fileInputStreamAudio = new ByteArrayInputStream(bytes1)
val bucketName = "Uploads"
val bucket = s3Service.createBucket(bucketName)

val fileObject = s3Service.putObject(bucket, {
                      val acl = s3Service.getBucketAcl(bucket)
                      acl.grantPermission(GroupGrantee.ALL_USERS,Permission.PERMISSION_READ)
                      val amazonPAth = UUID.randomUUID + "/audioFile.wav"
                      val tempObj = new S3Object(amazonPAth)
                      tempObj.setDataInputStream(fileInputStream)
                      tempObj.setAcl(acl)
                      tempObj.setContentType("audio/basic")
                      tempObj
                    })
                    s3AudioPath = s3Service.createUnsignedObjectUrl(bucketName, fileObject.getKey, false, false, false)

Поток сохраняется в хранилище s3 без ошибок. Когда я загружаю и играю файл .wav (тот, который я сохранил в хранилище s3), звук не воспроизводится. В то же время, когда я загружаю файл с локального диска, используя поток ввода файла, файл сохраняется в хранилище s3. Также скачанный аудиофайл с s3 воспроизводится без ошибок. Можно ли сохранить массив байтов в виде файла .wav в s3? Пожалуйста, помогите мне решить эту проблему. заранее спасибо


person mvm    schedule 11.11.2015    source источник


Ответы (1)


Я могу думать о двух возможностях здесь. Возможно, файл загружен не полностью, или в файле отсутствует заголовок WAVE.

Чтобы проверить первый случай, попробуйте посмотреть, одинакова ли сумма MD5 до и после загрузки файла.

Чтобы проверить второй случай, попробуйте добавить в файл заголовок WAVE. В вашем случае, поскольку у вас уже есть рабочий файл и сломанный файл, вы можете просто сравнить байты, чтобы увидеть, не связана ли проблема с заголовком.

Есть два способа добавить заголовок. Один из них — использовать AudioSystem.write. Он создает аудиофайл на диск. Ниже приведен пример создания аудиофайла на диске.

 public void publishToS3(final InputStream content) throws Exception {
        File wav = null;
        try {
            wav = convertToWav(content, key.replace('/', '-'));

            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setHeader(S3Repository.HEADER_ACL, S3Repository.HEADER_ACL_VALUE);
            metadata.setContentType("audio/x-wav");

            PutObjectRequest request = new PutObjectRequest(bucketName, key, wav);
            request.setMetadata(metadata);
            LOG.info("submitting {} to {}", key, bucketName);
            s3Client.putObject(request);
            LOG.info("submitted {} to {}", key, bucketName);
        } finally {
            if (wav != null && wav.delete()) {
                LOG.info("File {} removed", wav.getName());
            }
        }
 }

 private File convertToWav(final InputStream content, final String fileName) throws IOException {
        LOG.info("Creating file {}", fileName);
        File file = File.createTempFile("datamart-extract", fileName);
        file.deleteOnExit();
        AudioInputStream source = new AudioInputStream(content, AUDIO_FORMAT, -1);
        AudioSystem.write(source, AudioFileFormat.Type.WAVE, file);
        LOG.info("successfully created file {} at {}", file.getName(), file.getAbsolutePath());
        return file;
    }

Если вы не хотите сохранять аудиофайл на диск. Вам придется вручную добавить заголовок.

См. формат Wave http://www.topherlee.com/software/pcm-tut-wavformat.html

Полезная библиотека для создания заголовка волны: https://code.google.com/archive/p/musicg/

person Bryan Cheng    schedule 24.07.2019