This is a very puzzling issue that I've been around the block on several times here without coming to a solution. That question was getting too complicated to take all my updates and format correctly, so let's start fresh here.
The basic issue is that an audio clip is launched from a web page that has some kind of audio player on it. When the page appears, the browser does not know the duration of the clip, and the first time through, whatever UI the player has fails to show the player progressing through the file, even though it plays the clip audibly. Once the player has finished the clip, it has also learned the duration, and on a subsequent replay, the UI does show the progress.
This is the current state of play:
1) The original question assumed that jQuery jPlayer had something to do with the problem, but subsequent tests show that it does not. Removing jPlayer and instead using HTML5 audio tags shows exactly the same issue.
2) Originally I thought that the problem might lie with the SoX conversion of a .vox file to .wav, but a go-round on the SoX mailing list convinced me that this was not the case.
3) It's been suggested (primarily by Gyrocode.com) that the problem may lie with using .wav files, but I can reproduce the exact same problem with .ogg and other formats.
The only difference I can see between some of the samples that have been shown by Gyrocode and what I am doing is that my code initially puts in a dummy source, and then changes it dynamically before showing the audio player to the user (inside a modal dialog).
Below in skeletal form is the code.
HTML:
<div class="form-group">
<label class="col-sm-4 control-label">Play Audio</label>
<div class="col-sm-8">
<div style="box-sizing:content-box;" class="container" id="player-container">
<audio controls src="NONE" id="audio-player" preload="metadata"></audio>
</div>
</div>
</div>
JS:
/**
* JavaScript functions for populating data on the transcripts page.
*/
var oParams = new Object();
// temporarily hardcoded
oParams.userId="sc1478";
oParams.audioId="";
var oAudioList;
// loads the data table
function showModalTranscribeDialog(id) {
console.log( 'You clicked on the row for audio id '+id );
oParams.audioId=id;
$('#playTranscribeModal').modal('show');
}
function fnLoadAudio() {
console.log('in fnLoadAudio');
var url="x/audio/" + oParams.userId + "/";
console.log("searching " + url);
oAudioList = $('#audiolist').DataTable({
"pageLength" : 10,
"processing" : true,
"serverSide" : false,
"cache" : false,
"ajax" : {
"url" : url,
"dataSrc" : "payload.listOfAudio"
},
"columns" : [{
"data" : "audioId",
"title" : "Audio ID",
"width" : "6%"
}, ...
],
"columnDefs" : [
...
],
});
// clicking on row of table brings up modal dialog for playing and
// transcribing
$('#audiolist tbody').on('click', 'tr', function () {
var id = $('td', this).eq(0).text();
showModalTranscribeDialog(id);
} );
console.log('done with fnLoadAudio');
}
...
// load clip into audio player
function fnLoadPlayer() {
var alerted = false;
var media_url_wav='audio/clip/wav/'+oParams.audioId+'/';
console.log("player will play " + media_url_wav);
$("#audio-player").attr("src", media_url_wav);
}
$(document).ready(function() {
console.log('in document ready !!');
$('#dynamic').html( '<table cellpadding="0" cellspacing="0" border="0" class="display" id="audiolist"></table>' );
fnLoadAudio();
// set the ID of the selected audio in the dialog when the playTranscribe
//modal dialog is shown
$('#playTranscribeModal').on('show.bs.modal', function (e) {
...
fnLoadPlayer();
});
...
});
Here is what the code shows:
There is a JQuery Datatable on the page, and it also contains a modal dialog that pops up when a row of the table is clicked for further data gathering from the user. This dialog contains the audio player. The audio is played when the dialog is shown and the user clicks the play button.
The data table is loaded when the document is ready. The ready event handler calls fnLoadAudio() which fills in the data table and sets a click handler for when a row of table is clicked. In that event, the function showModalTranscribeDialog() is called. This first uses the row data to get the id of the audio to be played, and shows the dialog. Upon the dialog being shown another event handler uses the id to get the correct URL for the audio, and only then sets that into the src attribute of the element on the dialog.
The point this is illustrating is that the src attribute of the audio element is not populated until the dialog appears, although the audio element has been in the dialog (but hidden) all the while, with some other src value.
My theory is that it is this way of setting the src that is causing the problem, which will not occur when the audio's src is hardcoded on the page in a conventional manner.
And my question is whether there is a better way to dynamically set the source for the audio player, given the page structure as described.