cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - Learn all about the Community Ranking System, a fun gamification element of the PTC Community. X

Play particular MP3 file according to step

JD_9967989
5-Regular Member

Play particular MP3 file according to step

Hi everyone,

 

I'm looking for a solution how to play a particular audio according to the current step.
I already have a counter that displays the current step number of the sequence I'm playing, so for example if I start step 4 I'd like to play the uploaded MP3 file "audio4"

Many Thanks!

1 ACCEPTED SOLUTION

Accepted Solutions
JD_9967989
5-Regular Member
(To:JD_9967989)

Found a solution that works for me using switch()

I added a 3D Audio widget which is called "audio"

According to the current step which I get with

 

var stepNumber = $scope.app.view.Home.wdg["Model1"].currentStep;

 

I load the audio file into the widget and let it play. If 'stepNumber' is 1 it'll switch to 'case1' and so on. Haven't tried it with too many cases/files yet. Console logs are of course optional but my Vuforia Preview does not play any sound so I had to check in the console whether audios are executed. I ran it on the Hololens2 and it works just fine!

 

 

//play audio files according to step
$scope.playaudio= function(){

var stepNumber = $scope.app.view.Home.wdg["Model1"].currentStep;

switch(stepNumber){
case 1:
console.log(twx);
console.log($scope.app.view["Home"].wdg["audio"]);
$scope.app.view["Home"].wdg["audio"].audiosrc="app/resources/Uploaded/test1.mp3";
$scope.app.view["Home"].wdg["audio"].visible = true;
setTimeout(function(){
twx.app.fn.triggerWidgetService('audio', 'play');
}, 500);
break;
case 2:
console.log(twx);
console.log($scope.app.view["Home"].wdg["audio"]);
$scope.app.view["Home"].wdg["audio"].audiosrc="app/resources/Uploaded/test2.mp3";
$scope.app.view["Home"].wdg["audio"].visible = true;
setTimeout(function(){
twx.app.fn.triggerWidgetService('audio', 'play');
}, 500);
break;

}

View solution in original post

4 REPLIES 4
SC_9316022
5-Regular Member
(To:JD_9967989)

Hey! I found a way to do this, actually - today as well! But there are some problems.  I'll explain later.

 

So what I am doing is adding an Audio Widget to my 2D layout, then checking off "Visible" and "Show Controls" so that it's not visible to the user.

 

Next, I give this audio widget a specific Studio ID "audio1" for example.

 

In my JS file, I am also using a step counter within my $scope.watch statement, and use the twx function call to play the sound at that step:

                            twx.app.fn.triggerWidgetService('audio1', 'play');

 

This works great - until I have 23 steps and the user touches the "Next" step button, and there is no animation sequence.... the next audio step overlaps the current audio.  Likewise when the user touches "Back", the previous step audio will overlap any current audio.

 

I know how to prevent this in vanilla JS and even JQuery, but Vuforia is not allowing these functions, I am going to try this next:

 

twx.app.fn.triggerWidgetService('open2', 'pause'); //pausing original audio

$scope.view.wdg['open2'].audiosrc='';//setting that audio to nil

 

...this will of course have to be added to every step in my watch statement.... I'll let you know how it goes.... so happy someone else has the same question at literally the same day/time as me!  Let's work through it together!

 

                     

 

JD_9967989
5-Regular Member
(To:SC_9316022)

That helps a lot, thank you!

 

I'm quite new to coding and also vuforia, very happy to find motivated people here! I'm developing for the Hololens but should work similar! 

 

Atm my stepcounter runs with this function resulting in a string which I plan to use later for the audio (see 2) 

1) Stepcount

$scope.$on('newStep', function(evt,arg) {
var getStepRegex = /\((\d*)\//;
let new_arg=arg;
var numbers = new_arg.match(/\d+/g).map(Number);
var numB = numbers[0];
// convert the numbers to strings so they can be assigned to 3D label "text" property
var strB = numB.toString();
$scope.view.wdg['currStep']['text']=strB;
})

 

2) Play MP3

My Audio Widgets will all be called Audio1,Audio2,... and so on, hope this will do the job then:

 

//play audio files according to step
$scope.playaudio= function(){
twx.app.fn.triggerWidgetService('Audio'& strB, 'play');

}

 

Couldn't test though since my Vuforia Preview stopped working and I'll only be able to test it with the Hololens by tomorrow. 
I'll keep you posted!

JD_9967989
5-Regular Member
(To:JD_9967989)

Found a solution that works for me using switch()

I added a 3D Audio widget which is called "audio"

According to the current step which I get with

 

var stepNumber = $scope.app.view.Home.wdg["Model1"].currentStep;

 

I load the audio file into the widget and let it play. If 'stepNumber' is 1 it'll switch to 'case1' and so on. Haven't tried it with too many cases/files yet. Console logs are of course optional but my Vuforia Preview does not play any sound so I had to check in the console whether audios are executed. I ran it on the Hololens2 and it works just fine!

 

 

//play audio files according to step
$scope.playaudio= function(){

var stepNumber = $scope.app.view.Home.wdg["Model1"].currentStep;

switch(stepNumber){
case 1:
console.log(twx);
console.log($scope.app.view["Home"].wdg["audio"]);
$scope.app.view["Home"].wdg["audio"].audiosrc="app/resources/Uploaded/test1.mp3";
$scope.app.view["Home"].wdg["audio"].visible = true;
setTimeout(function(){
twx.app.fn.triggerWidgetService('audio', 'play');
}, 500);
break;
case 2:
console.log(twx);
console.log($scope.app.view["Home"].wdg["audio"]);
$scope.app.view["Home"].wdg["audio"].audiosrc="app/resources/Uploaded/test2.mp3";
$scope.app.view["Home"].wdg["audio"].visible = true;
setTimeout(function(){
twx.app.fn.triggerWidgetService('audio', 'play');
}, 500);
break;

}

SC_9316022
5-Regular Member
(To:JD_9967989)

Nice job!

 

My issue with multiple audio files playing simultaneously - I solved by simply hiding the navigation until the audio has ended, on each step.  

 

Since my audio files live in widgets on the 2D canvas, I could just use the Studio UI to make them not visible, and click on each widget and then bind the event "Play Ended" to a custom JS function.

 

$scope.showNext = function(){
     console.log('audio has ended for this sequence, revealing Next button');
     $scope.view.wdg['next']['visible'] = true;
}

 

Binding events in this way makes it super easy, but you could of course do all of it in code, with nothing physically on the 2D canvas.

Top Tags