2016-04-10 83 views

回答

1

當音頻上下文的採樣率與音頻文件的採樣率不同時,移動Safari中似乎沒有正確解碼加載音頻的錯誤。此外,音頻上下文的採樣率通常從44100到48000之間變化,但並不總是取決於網站是否加載iPhone聲音開啓或關閉。

此問題的解決方法是將讀出的音頻上下文的採樣速率,然後加載不同的音頻文件的每個採樣率,如下所示:

window.AudioContext = window.AudioContext || window.webkitAudioContext; 
var audio_context = new AudioContext(); 
var actual_sample_rate = audio_context.sampleRate; 
if (actual_sample_rate != 48000) { 
    actual_sample_rate = 44100; 
} 

function finished_loading_sounds(sounds) { 
    buffers['piano_do'] = { 
     buffer: sounds.piano, 
     rate: 1 
    }; 
    // ...do something when the sounds are loaded... 
} 

var buffer_loader = new BufferLoader(
    audio_context, 
    { 
     piano: "audio/" + actual_sample_rate + "/piano.m4a", 
    }, 
    finished_loading_sounds 
); 

buffer_loader.load(); 

緩衝加載器等在this tutorial定義。

要更改音頻文件的採樣率,可以使用Audacity


UPDATE

看來,即使當您嘗試加載具有正確的採樣率的文件時,偶爾的聲音仍然得到iOS設備上的扭曲。

要解決此問題,I found a hack for your AudioContext

function createAudioContext(desiredSampleRate) { 
    var AudioCtor = window.AudioContext || window.webkitAudioContext; 

    desiredSampleRate = typeof desiredSampleRate === 'number' 
     ? desiredSampleRate 
     : 44100; 
    var context = new AudioCtor(); 

    // Check if hack is necessary. Only occurs in iOS6+ devices 
    // and only when you first boot the iPhone, or play a audio/video 
    // with a different sample rate 
    if (/(iPhone|iPad)/i.test(navigator.userAgent) && context.sampleRate !== desiredSampleRate) { 
     var buffer = context.createBuffer(1, 1, desiredSampleRate); 
     var dummy = context.createBufferSource(); 
     dummy.buffer = buffer; 
     dummy.connect(context.destination); 
     dummy.start(0); 
     dummy.disconnect(); 

     context.close(); // dispose old context 
     context = new AudioCtor(); 
    } 
    return context; 
} 

然後使用它,創建音頻上下文如下:

var audio_context = createAudioContext(44100); 
2

使用脫機音頻上下文。類似以下內容可能會起作用:

var c = new OfflineAudioContext(1, len, 48000); 
var b = c.createBuffer(1, len, 44100); 
b.copyToChannel(yourSourceBuffer, 0); 
var s = c.createBufferSource(); 
s.buffer = b; 
s.connect(context.destination); 
s.start(); 
c.startRendering().then(function (result) { 
    // result contains the new buffer resampled to 48000 
}); 

根據實施情況,重採樣信號的質量可能會有所不同。