[英]Audio encoding issues in certain Android devices for online streaming playback
背景:
我正在開發一個Android移動應用程序,用戶在該應用程序中記錄音頻,然后將其上傳到服務器,然后可以在其中流回社區。
到目前為止,我們一直使用.WAV格式,該格式輸出很大的文件大小,以便通過移動網絡進行上傳和流式傳輸。 我正在轉換為.AAC格式,但是我了解到不同制造商會發生一些不同的問題。
問題:
然后這是主要問題。 將文件流傳輸到音頻播放器時,聲音播放器無法解碼僅在Samsung設備上記錄的音頻。 摩托羅拉和Nexus手機上記錄的AAC文件可與以前的WAV文件完美互換。 我可以直接在桌面上播放聲音文件,如果直接在Web瀏覽器中打開聲音文件,它們都可以播放。
當我使用AudioContext流化和解碼音頻時,會發生此問題。 我相信問題與三星音頻編解碼器中缺少標頭數據有關,但是我已經花了很多時間在此問題上,還沒有找到可行的解決方案。 這個問題看似直截了當,但花了我大量的精力才能弄清楚到底是什么問題。 任何幫助深表感謝。
我看到兩種方法:1.在Android應用程序的源代碼中解決編碼問題。2.糾正瀏覽器中的錯誤。 我看過有關使用函數嘗試重新同步流的帖子,但是我不完全了解如何實現此功能。
我認為最好的解決方案是#1。
我在瀏覽器中下載了兩個示例文件,並查看了原始數據以進行比較。 (原始數據快照http://i.imgur.com/tF6uHoO.png //我沒有足夠的聲譽來嵌入圖像,但稍后會進行修改。)
在Android RecordActiviy.java中記錄代碼
// FILE NAME
mFileName = "file.mp4";
// INITIATE MEDIA RECORDER
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mRecorder.setOutputFile(mFileName);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mRecorder.setAudioSamplingRate(48000);
mRecorder.setAudioEncodingBitRate(64000);
try {
mRecorder.prepare();
mRecorder.start();
} catch (IOException e) {
Log.e("AUDIO RECORDING", "prepare() failed");
e.printStackTrace();
}
}
...
getSound.php
...
$File = $path . $filename;
switch($filetype){
case 'wav':
//FILE TYPE WAV
$mime_type = "audio/vnd.wave";
header("Content-type: ".$mime_type);
$test = readfile($file);
break;
case 'mp4':
//FILE TYPE MP4
//$mime_type = "audio/mp4";
$mime_type = "audio/aac";
header("Content-type: ".$mime_type);
$test = readfile($file);
break;
default:
break;
}
soundPlayer.js
...
var player;
function loadPlayer() {
player = new SoundPlayer();
..UI and other stuff..
}
// Build Sound Player Object
function SoundPlayer() {
this.arrayBuffer = null; //array buffer of audio data
this.context = new AudioContext(); //browser sound context
this.duration = null; //Length of audio clip
this.source = null; //Converted audio source
this.trueEnd = true; //Check to see if sound ended due to completion
this.isPlaying = false; //Check to see if sound is currently playing
this.t = 0; //Update variable for time counter
this.startTime = null; //Start time of audio is logged when playAudio()
this.byteData = null;
var sp = this; // sp = soundPlayer (Reference to SoundPlayer obj)
this.playAudio = function() {
this.source = null;
/* ArrayBuffer must be decoded each time play is called
* due to the nature of a decoded AudioBuffer only
* being able to be played once */
sp.context.decodeAudioData(sp.arrayBuffer, decoded);
sp.t = setInterval(updateProgress, 10);
};
this.loadSound = function(pid) {
$.ajax({
async: true,
url: "getSound.php",
data: { soundID: sID },
beforeSend: function(xhr) {
//Allow for binary data
xhr.overrideMimeType("text/plain; charset=x-user-defined");
},
success: function(dataAsString) {
dataAsString = dataAsString.trim();
if( dataAsString.localeCompare("") == 0 ){
alert("Sound File Not Found");
return;
}
// convert string to byte array
var bytes = [];
var i, l = dataAsString.length;
for (i = 0; i < l; ++i) {
bytes.push(dataAsString.charCodeAt(i) & 0xFF);
}
sp.byteData = bytes;
//Convert byte array into audio buffer
var arrayBuffer = new ArrayBuffer(bytes.length);
var bufferView = new Uint8Array(arrayBuffer);
for (var i = 0; i < bytes.length; i++) {
bufferView[i] = bytes[i];
}
sp.arrayBuffer = arrayBuffer;
//get sound duration info
sp.context.decodeAudioData(arrayBuffer, function(buffer) {
sp.duration = buffer.duration;
notify_UI_load_complete();
}, function(error){
**** // WE GET TO THIS BLOCK IN THE BROWSER
**** // RETURNS UNDEFINED
console.log("error decoding "+ arrayBuffer.length);
console.log(arrayBuffer);
console.log("error type "+ error);
});
},
error: function(jqXHR, textStatus, errorThrown) {
console.log("load error");
console.log(textStatus, errorThrown);
alert("Could not load specific sound file");
}
});
}
...
TL; DR Android音頻WebContext中的Android Samsung AAC音頻流錯誤。 網絡音頻很難。 我們可以得到一個通用標准了嗎?
音頻文件具有元數據信息。 在某些文件中,它位於文件末尾。 在這種情況下,這些文件僅在完全下載后才能播放,即無法流式傳輸。
為了使這些文件可流式傳輸,您需要將元數據信息移動到音頻文件的開頭。 您可以使用MP4Box:
MP4Box -v -inter 300 old.mp4 -out new.mp4
其中300是以毫秒為單位的交織。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.