Skip to content

Commit

Permalink
Add support for .ogg, .flac, .aac, and others
Browse files Browse the repository at this point in the history
Instead of throwing an error, unknown audio formats will be interpreted
by the system's AudioContext and encoded as a wav instead.
File sizes are pretty bad, but this is still net improvement.
ScratchAddons/ScratchAddons#6515 (comment)
  • Loading branch information
GarboMuffin committed Aug 15, 2023
1 parent 7057f92 commit 1c6e353
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/containers/sound-tab.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ class SoundTab extends React.Component {
title: intl.formatMessage(messages.fileUploadSound),
img: fileUploadIcon,
onClick: this.handleFileUploadClick,
fileAccept: '.wav, .mp3',
fileAccept: '.wav, .mp3, .ogg, .flac, .aac',
fileChange: this.handleSoundUpload,
fileInput: this.setFileInput,
fileMultiple: true
Expand Down
7 changes: 6 additions & 1 deletion src/lib/file-uploader.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import randomizeSpritePosition from './randomize-sprite-position.js';
import bmpConverter from './bmp-converter';
import gifDecoder from './gif-decoder';
import fixSVG from './tw-svg-fixer';
import convertAudioToWav from './tw-convert-audio-wav.js';

/**
* Extract the file name given a string of the form fileName + ext
Expand Down Expand Up @@ -211,7 +212,11 @@ const soundUpload = function (fileData, fileType, storage, handleSound, handleEr
break;
}
default:
handleError(`Encountered unexpected file type: ${fileType}`);
convertAudioToWav(fileData)
.then(fixed => {
soundUpload(fixed, 'audio/wav', storage, handleSound, handleError);
})
.catch(handleError);
return;
}

Expand Down
21 changes: 21 additions & 0 deletions src/lib/tw-convert-audio-wav.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import SharedAudioContext from './audio/shared-audio-context';
import WavEncoder from 'wav-encoder';

const convertAudioToWav = fileData => {
/** @type {AudioContext} */
const audioContext = new SharedAudioContext();

return audioContext.decodeAudioData(fileData)
.then(decodedData => {
const channels = [];
for (let i = 0; i < decodedData.numberOfChannels; i++) {
channels.push(decodedData.getChannelData(i));
}
return WavEncoder.encode({
sampleRate: decodedData.sampleRate,
channelData: channels
});
});
};

export default convertAudioToWav;

0 comments on commit 1c6e353

Please sign in to comment.