2

What I want to achieve is create a custom binding for Knockout.js which enables to bind to model and play defined audio file using HTML5 audio tag when that observable changes. so for example it would look something like

<p data-bind="audio: {value: someobservable, sound:'pathto/sound.mp3'}"><?p>

as far as I understand this must bu custom knockout binding which has init and update methods and on init it checks if any audio tag is presented in DOM and create one in case there is no audio tag and play sound value in case value property changes. as far as I understand I must internally subscribe to value binding but could not get exact idea how to implement that. could anyone help me out there?

Rati_Ge
  • 1,262
  • 2
  • 15
  • 37
  • 1
    Have you read [the Knockout documentation about creating a custom binding](http://knockoutjs.com/documentation/custom-bindings.html)? It contains samples you can look at. Also, please edit your question and add what you have tried and what errors you get in your attempts. – Robert Westerlund Mar 05 '14 at 07:20
  • sure i did i created a lots of bindings before that the only problem was related with audio binding. I am not asking for code all I want is direction or some hints about how to work with html5 audio? should i use jQuery for that? – Rati_Ge Mar 05 '14 at 07:26
  • Why do you want to create a the audio tag dynamically? Why don't you just create a custom binding which you put on an existing audio tag which plays the file when the observable changes? – nemesv Mar 05 '14 at 07:26

1 Answers1

1

You don't need to create an audio tag, you can just use the JavaScript audio API to play a sound if the observable changes:

ko.bindingHandlers.audio = {
    init: function (element, valueAccessor) {
        var config = ko.unwrap(valueAccessor());
        var file = config.sound;
        var observable = config.value;
        observable.subscribe(function () {
            var audio = new Audio(file);
            audio.play();
        });
    }
};

And you can use it as in your question:

<p data-bind="audio: {value: someobservable, 
                 sound:'http://www.w3schools.com/TAGs/horse.ogg'}">SOme test</p>

Demo JSFiddle.

Community
  • 1
  • 1
nemesv
  • 138,284
  • 16
  • 416
  • 359
  • even i was not asking for concrete code implementation var observable = config.value; observable.subscribe(function () { var audio = new Audio(file); audio.play(); }); this was code i was looking for. my only question is how this performance and does it has big impact on performance if it fires often? and is it cross browser solution? – Rati_Ge Mar 05 '14 at 07:46
  • 1
    it will fire every time when your `someobservable` changes or the whole config changes. and it should be supported by every browser which supports the audio tag: http://caniuse.com/audio – nemesv Mar 05 '14 at 07:47
  • for some reason it does not work in IE (v11). I will try to find it out. – Rati_Ge Mar 05 '14 at 08:05
  • It can be either a format problem, or IE does not like play sound from a different domain... I get access Access is denied. errors. Or it can be a problem of the JSFiddle... or do you experience this problem also locally? – nemesv Mar 05 '14 at 08:10
  • I experience this problem locally as well i think it is more related to file format problem. – Rati_Ge Mar 05 '14 at 10:29
  • 1
    so the problem was related to the file extension i changed it to .mp3 and everything works again – Rati_Ge Mar 06 '14 at 10:30