Reputation: 303
In my scala application I call s3 storage service to upload my byte array input stream. I want this input stream to be stored as a .wav file. The code is as below
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)
The stream is stored to the s3 storage without any error. When I download and play the .wav file(the one I stored to the s3 storage) the audio is not playing. At the same time when I upload a file from the local disk using file input stream the file gets stored to the s3 storage. Also the downloaded audio file from s3 plays without any error. Is it possible to store the byte array as .wav file in s3? Please help me to fix this issue. Thanks in advance
Upvotes: 3
Views: 1421
Reputation: 433
I can think of two possibilities here. The file might not be uploaded completely, or the file is missing the WAVE header.
To check the first case, try see if the MD5sum is the same before and after uploading the file.
To test the second case, try adding the WAVE header to the file. In your case, since you already have a working file and a broken file, you can simply compare the bytes to see if it is an issue with the header.
There are two ways to add the header. One is to use AudioSystem.write
. It constructs an audio file to the disk.
Below is an example of contructing a audio file on disk.
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;
}
If you do not want to store the audio file to the disk. You will have to manually append the header.
See Wave format http://www.topherlee.com/software/pcm-tut-wavformat.html
Helpful library for constructing Wave header: https://code.google.com/archive/p/musicg/
Upvotes: 1