New Feature: Audio Component

Hello everyone, I’m happy to announce the release of the Audio component that will be available on the nightly builds. The primary purpose of this component is to allow users to play audio in Perspective, providing both the component, scripting functions for the component, and events. Of course, how can we forget the opportunities to Rick Roll your fellow operators.

The Audio component comes in two flavors that is driven by the display property of the component. By default, the display property Audio component is set to false. This allows designers to add audio without having to worry about the component affecting document flow and the layout of their Views. Instead, one can use the provided scripting functions to play/ pause media files. When the Audio component is set to be displayed, the Audio component will use the user agent’s default UI for controls. Here is an example of the Audio component in Chrome:

audio

Properties

source: string - The URL of the media file.
play: boolean - The play state of the media file. Will be kept in sync with with the user agent’s UI controls and any scripting functions called.
loop: bolean - Determines if the media file should be looped.
volume: number - Determines the volume of the media file.
playbackRate: number - Determines the playback rate of the media file. Note: Some browsers may mute the audio if certain ranges of playback rate are exceeded.
allowDownload: boolean - Determines if the browser’s UI should display the download button. This depends whether or not the specific user agent implements the UI with a download button.
display: boolean - Determines if the Audio component should be rendered.
style: StyleObject - The style of the Audio component.

Events

onPlay - Event fired when the media file is playing. Note: If the Audio component is set to loop, this event will fire on every loop.
onPause - Event fired when the media file is paused.
onError - Event fired when the Audio component encounters an error.

  • errorMessage: string - The message when encountering an error.

onEnded - Event fired when the media file has reached the end. Note: If the Audio component is set to loop, this event will fire on every loop.
onLoaded - Event fired when the media file has loaded its first playable frame. Note: Be aware that if the intention is to call play() in this event, some user agent’s may block you from doing so until the user has interacted with the client.
onRateChanged - Event fired when the media file playback rate is changed.

Scripting Functions

play() - Play the media file of the Audio component.
pause() - Pause the media file of the Audio component.
replay() - Set the time of the media file back to 0 and play the media file of the Audio component.


That concludes the overview. Feel free to give this component a try and post any feedback below. Thanks!
10 Likes

Got my image ready to go.

8 Likes

Will there be a video component in the future?

Hey Jordan,

The video player is already available as a component in Perspective, unless this is an elaborate ploy to troll me :laughing:.

Yay, now I can add twinkle noises every time someone clicks on a button :smiley:

7 Likes

I was more thinking of a randomized smoke detector chirp :sweat_smile:

9 Likes

Will the sound source file have to be local to the client, or can a source point to a file located on the gateway?

For anything in Perspective, you can safely assume that the source file cannot be local.

Hi @cmgriggs93,

Yes you can have a file located on the gateway. For example, you can upload an audio file through the WebDev module and use the mounted url as the source for the audio component.

Out of curiosity, apart from the version of the audio component that can still play audio while its display property is set to false, what is the expected use case for this component? I have always just used the video player component for this.

Hi @swolnisty,

Functionally between the two there is no difference if I take advantage of theming and set the video components video display to none but keep the controls displayed. There may be some file format differences, potentially MP3, that may not be recommended to be used in the underlying video element of the component. However, I’ve yet to find hard evidence to support this. Perhaps the only difference is aesthetics, whether you’d prefer our custom-built UI or the user agent’s (browser’s) UI for controls.

1 Like

Can this be used to play an alarm sound every time there is an unknowledged active alarm?

Should be doable with an expression binding on the play property using isAlarmActiveFiltered

I didnt test this, may have gotten the flags wrong:

isAlarmActiveFiltered("[default]*", "*", "*", 0, 4, 0, 0, 0)

Meh i couldnt get that to work, try this:

runScript('len(system.alarm.queryStatus( state=["ActiveUnacked"]))', 2500)
1 Like

Hi @dmachuca,

Sure, adding onto what @josborn has already provided. Once you’ve set up a way to detect unacked alarms, you can also call self.play() or self.getSibling(…).play() in a scripting function, depending on where your script is defined.

1 Like

Don’t call this on your view though unless you will only have a very small number of clients. It’s scales horribly, and never call this in Vision

A fair point. I actually wouldn’t do this at all, i handle all of this in the PLC and have a Boolean that triggers the sound player.

Ok, so now i am curious. I did both of these on a dev environment to see what the impact was, and i found nothing. It may be that my setup just didnt have much going on but loading multiple vision clients with the binding above and 30+ perspective sessions there was no appreciable change in memory, cpu , or ui responsiveness. Just for my understanding can you tell me what you would expect to see performance wise?

At a customer of ours with 120 clients (~80 vision ~40 perspective), calling system.alarm.queryStatus would kill the gateway. You can see this with the load that the alarm status tables in older 8.1 versions place on the gateway which call this. Last year we were using these in 8.1.5 on a single gateway system and the CPU usage was through the roof and was crashing the server all the time, not to mention destroying client performance. In later versions I think after 8.1.10? they added caching to reduce the need to query the alarm table every time.

Back in my old Ignition days, in my naive wisdom I created an alarm summary Template in Vision which called system.alarm.queryStatus to count the number of alarms given a tagPath. This was on a very small 3-client system with decently-resourced clients, and I had maybe 5-10 of these templates on the page at any one time. Operators complained for weeks about terribly slow performance; clicking nav links or opening popups would take 5-10s to even start to load, very slow to write to tags. In the end, I removed these templates from the screens and all of a sudden no more issues.

Thanks for the background Information. All of my setups would be extremely small compared to what you have described which is probably why i didn’t notice the hit. My cpu usage is nearly always in single digit territory.