简体   繁体   中英

Meteor.js : I want to play a sound when someone recieves a message in a simple chat app

On my PC I get a sound in chrome browser when I send a message via my smart phone (android) But on my phone I don't get a sound. I tested this with 2 laptops and it works now with those but my phone's browser does not give a beep. The goal is that I get a sound when I receive a message. The strange thing is that my phone gives a sound when I use the standard meteor example app. I mean when you create your app with meteor create you get a skeleton code and I inserted "new Audio('path to sound file').play(); into the click event. It works perfectly!

But in my app it only works sometimes and never on my mobile. I use the same audio file and have it in my public folder of the meteor app.

var msgId=0;
var old=Session.get('msgCount');

Template.berichtenlijst.messages=function(){

    if(old<Session.get('msgCount')){//there is a new message in Message collection

        old=Session.get('msgCount');

        var array=Messages.find().fetch();

        if(array.length>0&&(msgId!==array[array.length-1]._id)){
            //notify new message

            new Audio('audio.mp3').play();
        }

    }



    return Messages.find({}, { sort: { timestamp: -1 },limit:100});


}

msgId has a value, the id is from Messages.insert(..) I have debugged that and that is right. Also the SESSION variable is the right one. And with the example app I get the sound also on mobile. I have no idea what is going on. Sorry I know it might be a vague question but it is a vague problem to me.

I think a lot of mobile browsers limit your ability to play sounds that aren't in direct response to a user action.

So, you can play a sound in the callback of a click eventListener... but you can't do it at an arbitrary time (say, as a response to a websocket message).

Also: traditionally you'd want to wait to call play until the canplaythrough event has fired on the audio element, so something like this:

var audio = new Audio('audio.mp3');
audio.addEventListener('canplaythrough', function() {
  audio.play();
});

I have been successful using buzz.js ( https://github.com/brentjanderson/meteor-buzz.git ). I had tried using Audio before with lots of compatibility issues, whereas it might work in the most modern browsers but not in reactive settings.

The application plays sounds based on reactive events both from updating session and collections and is working fine in an android app as well as in most modern browsers. However on android I've noticed that only one sound can be played at each time (successive play attempts cancel the currently playing sound out).

Playing sound is very simple:

var audio = new buzz.sound('/sounds/warning.mp3');
audio.play();

This is overly difficult, would have been nice to have a "On New Data Function".

Instead, you need to spit out unique ID's for each message. Then use Jquery to scan for the last one every 1 second. Store that last ID in a client side memory, I'm just using a window variable. Then, if the last message id changes in the next second, play a sound.

But in this method, you'll get your own message sounds. So, add more complexity. Also store your userId() in client memory, and compare if the new message is from myself, or another user.

{{#each chatMessages}}

                                        <div class="chat-message left" id="chatMessage_{{_id}}">
                                            <div id="owner_id" style="display:none;">{{owner_id}}</div>
                                            <a class="message-author" href="/people/{{username}}">
                                                <img class="message-avatar" src="{{avatar}}" alt="">
                                            </a>
                                            <div class="message">
                                                <a class="message-author" href="/people/{{username}}">{{title}}</a>
                                                <span class="message-date">{{timeAgo}}</span>
                                                    <span class="message-content">
                                                    {{content}}
                                                    </span>
                                            </div>
                                        </div>

                                    {{/each}}

    // Set last message seen on client
window.chatMessage_messageId = $(".chat-message:last").attr("id");
window.chatMessage_userId = $(".chat-message:last").attr("id");

setInterval( function(){ 

    // New message?
    if(window.chatMessage_messageId != $(".chat-message:last").attr("id") ){

        // Do I own this? (no sound)
        var owner = $("#"+window.chatMessage_messageId+" #owner_id").html();
        if(owner != Meteor.userId()){
            window.chatMessage_messageId = $(".chat-message:last").attr("id");

            ringAudio = new Audio('/sounds/chat_message.mp3'); 
            ringAudio.pause();
            ringAudio.currentTime = 0;
            ringAudio.play();
        }

    }

}, 1000);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM