Merge pull request #1383 from paulkaplan/fix-safari-audio
Fix several safari audio issues
This commit is contained in:
3 files changed
+30
-15
No files matched your search
@@ -16,7 +16,7 @@ class SoundEditor extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
bindAll(this, [
|
||||
'copyCurrentSamples',
|
||||
'copyCurrentBuffer',
|
||||
'handleStoppedPlaying',
|
||||
'handleChangeName',
|
||||
'handlePlay',
|
||||
@@ -70,7 +70,7 @@ class SoundEditor extends React.Component {
|
||||
if (this.undoStack.length >= UNDO_STACK_SIZE) {
|
||||
this.undoStack.shift(); // Drop the first element off the array
|
||||
}
|
||||
this.undoStack.push(this.copyCurrentSamples());
|
||||
this.undoStack.push(this.copyCurrentBuffer());
|
||||
}
|
||||
this.resetState(samples, sampleRate);
|
||||
this.props.onUpdateSoundBuffer(
|
||||
@@ -102,12 +102,12 @@ class SoundEditor extends React.Component {
|
||||
if (this.state.trimStart === null && this.state.trimEnd === null) {
|
||||
this.setState({trimEnd: 0.95, trimStart: 0.05});
|
||||
} else {
|
||||
const samples = this.copyCurrentSamples();
|
||||
const {samples, sampleRate} = this.copyCurrentBuffer();
|
||||
const sampleCount = samples.length;
|
||||
const startIndex = Math.floor(this.state.trimStart * sampleCount);
|
||||
const endIndex = Math.floor(this.state.trimEnd * sampleCount);
|
||||
const clippedSamples = samples.slice(startIndex, endIndex);
|
||||
this.submitNewSamples(clippedSamples, this.props.sampleRate);
|
||||
this.submitNewSamples(clippedSamples, sampleRate);
|
||||
}
|
||||
}
|
||||
handleUpdateTrimEnd (trimEnd) {
|
||||
@@ -119,9 +119,12 @@ class SoundEditor extends React.Component {
|
||||
effectFactory (name) {
|
||||
return () => this.handleEffect(name);
|
||||
}
|
||||
copyCurrentSamples () {
|
||||
copyCurrentBuffer () {
|
||||
// Cannot reliably use props.samples because it gets detached by Firefox
|
||||
return this.audioBufferPlayer.buffer.getChannelData(0);
|
||||
return {
|
||||
samples: this.audioBufferPlayer.buffer.getChannelData(0),
|
||||
sampleRate: this.audioBufferPlayer.buffer.sampleRate
|
||||
};
|
||||
}
|
||||
handleEffect (name) {
|
||||
const effects = new AudioEffects(this.audioBufferPlayer.buffer, name);
|
||||
@@ -133,18 +136,18 @@ class SoundEditor extends React.Component {
|
||||
});
|
||||
}
|
||||
handleUndo () {
|
||||
this.redoStack.push(this.copyCurrentSamples());
|
||||
const samples = this.undoStack.pop();
|
||||
this.redoStack.push(this.copyCurrentBuffer());
|
||||
const {samples, sampleRate} = this.undoStack.pop();
|
||||
if (samples) {
|
||||
this.submitNewSamples(samples, this.props.sampleRate, true);
|
||||
this.submitNewSamples(samples, sampleRate, true);
|
||||
this.handlePlay();
|
||||
}
|
||||
}
|
||||
handleRedo () {
|
||||
const samples = this.redoStack.pop();
|
||||
const {samples, sampleRate} = this.redoStack.pop();
|
||||
if (samples) {
|
||||
this.undoStack.push(this.copyCurrentSamples());
|
||||
this.submitNewSamples(samples, this.props.sampleRate, true);
|
||||
this.undoStack.push(this.copyCurrentBuffer());
|
||||
this.submitNewSamples(samples, sampleRate, true);
|
||||
this.handlePlay();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,13 @@ class AudioBufferPlayer {
|
||||
stop () {
|
||||
if (this.source) {
|
||||
this.source.onended = null; // Do not call onEnded callback if manually stopped
|
||||
this.source.stop();
|
||||
try {
|
||||
this.source.stop();
|
||||
} catch (e) {
|
||||
// This is probably Safari, which dies when you call stop more than once
|
||||
// which the spec says is allowed: https://developer.mozilla.org/en-US/docs/Web/API/AudioBufferSourceNode
|
||||
console.log('Caught error while stopping buffer source node.'); // eslint-disable-line no-console
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,8 +38,14 @@ class AudioEffects {
|
||||
buffer.getChannelData(0).reverse();
|
||||
break;
|
||||
}
|
||||
const OfflineAudioContext = window.OfflineAudioContext || window.webkitOfflineAudioContext;
|
||||
this.audioContext = new OfflineAudioContext(1, sampleCount, buffer.sampleRate);
|
||||
if (window.OfflineAudioContext) {
|
||||
this.audioContext = new window.OfflineAudioContext(1, sampleCount, buffer.sampleRate);
|
||||
} else {
|
||||
// Need to use webkitOfflineAudioContext, which doesn't support all sample rates.
|
||||
// Resample by adjusting sample count to make room and set offline context to desired sample rate.
|
||||
const sampleScale = 44100 / buffer.sampleRate;
|
||||
this.audioContext = new window.webkitOfflineAudioContext(1, sampleScale * sampleCount, 44100);
|
||||
}
|
||||
this.buffer = buffer;
|
||||
this.source = this.audioContext.createBufferSource();
|
||||
this.source.buffer = this.buffer;
|
||||
|
||||
Reference in new issue
Block a user