Audio elements missing from index_lms_html5

Hi all.

Both the story.html and story_html5.html, when run locally or off a web server, have <audio> elements appended to them. This has allowed me to write a script that will find all the <audio> elements on a page, and pause/mute them. This works perfectly when running locally.

I uploaded the same course to scormcloud, everything works fine in IE, I can see the <audio> elements fine and I can control them using Javascript. In Chrome, the elements are not generated, or if they are then they are only created for the duration that the audio plays (nothing seems to suggest that this is how it works).

My first thought, upon seeing that there are no <audio> elements, was that maybe they are being created as Javascript objects, using new audio(), but I can't find any code in the entire output that would suggest this.

The network tab of the Chrome developer tools shows that all of audio files are loading, so the issue can't be around files not loading correctly.

How is the audio still playing when there are no <audio> elements or audio objects?

How can I use Javascript to control these non-existent audio objects?

Any insight into how (or why?!) audio is generated differently when run off of an LMS would be great.

9 Replies
chiefy .

For those interested in a fix, so you can play with audio using javascript, replace the function on line 29,238 with the following -

"use strict";
var t = e("lodash"),
i = e("helpers/audio/AudioClipBase"),
n = e("helpers/utils"),
s = n.createSuper(i),
r = document.body,
o = {},
a = function() {
i.apply(this, arguments)
};
return t.extend(a, i), a.prototype = new i, t.extend(a.prototype, {
constructor: a,
initialize: function() {
s("initialize").apply(this, arguments), this.dfd.fail(function() {
delete o[this.url]
}.bind(this)), this.playTimeout = null, this.updateTimeDelegate = this.updateTime.bind(this)
},
onEnded: function() {
this.startTime = this.getDuration(), s("onEnded").call(this, arguments)
},
updateTime: function(e) {
this.onTimeUpdateDelegate(e.target.currentTime)
},
load: function() {
return null == o[this.url] ? (this.el = new window.Audio, this.el.setAttribute("preload", "auto"), this.el.src = this.url, r.appendChild(this.el), this.el.load(), o[this.url] = this.el) : (this.el = o[this.url], this.el.readyState >= this.el.HAVE_ENOUGH_DATA && this.dfd.resolve()), this.el.addEventListener("canplaythrough", this.dfd.resolve), this.el.addEventListener("error", this.dfd.reject), this.el.addEventListener("ended", this.onEndedDelegate), this.el.addEventListener("timeupdate", this.updateTimeDelegate), this
},
deferredPlay: function() {
var e = this.el.play.bind(this.el);
this.clearPlayTimeout(), this.startAt < this.getDuration() ? (this.startAt < 0 ? (this.negative = !0, this.el.pause(), this.setCurrentTime(0), this.playTimeout = setTimeout(e, n.toMilliseconds(-this.startAt))) : (this.negative = !1, this.setCurrentTime(this.startAt), e()), this.performanceStartTime = (new Date).getTime(), this.isPlaying = !0) : (this.pause(), this.onEnded())
},
deferredPause: function() {
this.isPlaying && (this.clearPlayTimeout(), 0 === this.el.currentTime && this.negative ? this.startAt = n.toSeconds((new Date).getTime() - this.performanceStartTime) + this.startAt : this.startAt = this.el.currentTime, this.el.pause(), this.isPlaying = !1)
},
getDuration: function() {
return this.el.duration
},
setVolume: function(e) {
return this.el.volume = e, this
},
setCurrentTime: function(e) {
this.el.currentTime !== e && (this.el.currentTime = e)
},
destroy: function(e) {
return this.clearPlayTimeout(), null != this.el && (this.el.removeEventListener("canplaythrough", this.dfd.resolve), this.el.removeEventListener("error", this.dfd.reject), this.el.removeEventListener("ended", this.onEndedDelegate), this.el.removeEventListener("timeupdate", this.updateTimeDelegate), e || (r.removeChild(this.el), delete o[this.url])), s("destroy").apply(this, arguments), this
},
clearPlayTimeout: function() {
clearTimeout(this.playTimeout), this.playTimeout = null
}
}), a

This is the same code that is used to generate the <audio> elements when viewing a course locally.

Ashley Terwilliger-Pollard

Hi chiefy, 

Sorry for the delay in getting to you here! As a note for future, our team is always monitoring the forums but we're reading oldest to newest, so new comments may keep this out of our view for a bit. 🙂  

If you ever need immediate assistance, you're always welcome to contact our Support team here. They're around 24/7! 

I took a look at the information you shared, and it's a bit beyond the scope of what we support when it comes to Javascript and modifications of our published output. I can ping a few members of our team to see if they can weigh in, but I know there are a handful of ELH community members who are Javascript pros - so I hope they can shed some light on this for you too! 

Thanks, and let me know if you need anything else.