How do I turn the mic off? - firefox-os

I'm using navigator.getUserMedia for a voice memo app. It works like a charm.
When I quit the app, the microphone stays on (there is a notification "Audio Memos Mic is on" and the red dot remains in the status bar. It stays on even after the phone went to sleep for fifteen minutes.
How do I turn the mic off when I quit the app. I've check the mediastream API but couldn't find any reference.

Have you tried the stop method: https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder.stop
There may be a better way but I got the light to turn off on minimized apps by using code similar to:
mediaRecorder was a ref to the MediaRecorder object tied to the stream. You can also just call stop on the stream returned by the GetUserMedia call. Also had to call setup on init of app as well.
function handleVisibilityChange() {
if (document.hidden) {
console.log("hidden");
if( gumStream ){
gumStream.stop();
mediaRecorder = null;
}
} else {
console.log("visible");
setup(); //Call getUserMedia
}
}
document.addEventListener("visibilitychange", handleVisibilityChange, false);

Related

How can I get who paused the video in Youtube API? (with Socket.io)

Basically, I'm challenging myself to build something similar to watch2gether, where you can watch youtube videos simultaneously through the Youtube API and Socket.io.
My problem is that there's no way to check if the video has been paused other than utilizing the 'onStateChange' event of the Youtube API.
But since I cannot listen to the CLICK itself rather than the actual pause EVENT, when I emit a pause command and broadcast it via socket, when the player pauses in other sockets, it will fire the event again, and thus I'm not able to track who clicked pause first NOR prevent the pauses from looping.
This is what I currently have:
// CLIENT SIDE
// onStateChange event
function YtStateChange(event) {
if(event.data == YT.PlayerState.PAUSED) {
socket.emit('pausevideo', $user); // I'm passing the current user for future implementations
}
// (...) other states
}
// SERVER SIDE
socket.on('pausevideo', user => {
io.emit('smsg', `${user} paused the video`)
socket.broadcast.emit('pausevideo'); // Here I'm using broadcast to send the pause to all sockets beside the one who first clicked pause, since it already paused from interacting with the iframe
});
// CLIENT SIDE
socket.on('pausevideo', () => {
ytplayer.pauseVideo(); // The problem here is, once it pauses the video, onStateChange obviously fires again and results in an infinite ammount of pauses (as long as theres more than one user in the room)
});
The only possible solution I've thought of is to use a different PLAY/PAUSE button other than the actual Youtube player on the iframe to catch the click events and from there pause the player, but I know countless websites that uses the plain iframe and catch these kind of events, but I couldn't find a way to do it with my current knowledge.
If the goal here is to be able to ignore a YT.PlayerState.PAUSED event when it is specifically caused by you earlier calling ytplayer.pauseVideo(), then you can do that by recording a timestamp when you call ytplayer.pauseVideo() and then checking that timestamp when you get a YT.PlayerState.PAUSED event to see if that paused event was occurring because you just called ytplayer.pauseVideo().
The general concept is like this:
let pauseTime = 0;
const kPauseIgnoreTime = 250; // experiment with what this value should be
// CLIENT SIDE
// onStateChange event
function YtStateChange(event) {
if(event.data == YT.PlayerState.PAUSED) {
// only send pausevideo message if this pause wasn't caused by
// our own call to .pauseVideo()
if (Date.now() - pauseTime > kPauseIgnoreTime) {
socket.emit('pausevideo', $user); // I'm passing the current user for future implementations
}
}
// (...) other states
}
// CLIENT SIDE
socket.on('pausevideo', () => {
pauseTime = Date.now();
ytplayer.pauseVideo();
});
If you have more than one of these in your page, then (rather than a variable like this) you can store the pauseTime on a relevant DOM element related to which player the event is associated with.
You can do some experimentation to see what value is best for kPauseIgnoreTime. It needs to be large enough so that any YT.PlayerState.PAUSED event cause by you specifically calling ytplayer.pauseVideo() is detected, but not so long that it catches a case where someone might be pausing, then unpausing relatively soon after.
I actually found a solution while working around what that guy answered, I'm gonna be posting it in here in case anyone gets stuck with the same problem and ends up here.
Since socket.broadcast.emit doesn't emit to itself, I created a bool ignorePause and made it to be true only when the client received the pause request.
Then I only emit the socket if the pause request wasn't already broadcasted and thus received, and if so, the emit is ignored and the bool is set to false again in case this client/socket pauses the video afterwards.

Getting a sound trigger to work

I don't understand why my sound trigger is not working. I have created a GameObject and added an Audio Source to it (on Audio Source I have the Play On Wake and Loop checked. Then I added a Sphere Collider (I have the Is Trigger checked). Finally I added my script and added the sound clips into the inspector. Unity also says that: "There are 2 audio listeners in the scene." I have pretty much unchecked all the audio listeners and it still says it, what am I doing wrong?
Here is a look at my code:
#pragma strict
var WalkAudio:AudioClip;
var OutCry:AudioClip;
function Update (){
var Audio= gameObject.GetComponent(AudioSource);
if(Input.GetButton("Horizontal") || Input.GetButton("Vertical"))
{
Audio.Play();
}
else
{
Audio.Pause();
}
}
function OnControllerColliderHit (hit : ControllerColliderHit)
{
var Audio= gameObject.GetComponent(AudioSource);
if (hit.gameObject.tag == "templeFloor")
{
var groundType = 1;
print("Temple");
Audio.clip=OutCry;
}
else{
Audio.clip=WalkAudio;
}
}
As you said:
I have pretty much unchecked all the audio listeners
The component AudioListener attached to the Main Camera must be enabled. Probably you have used LoadLevelAdditive so you have two camera and two AudioListener components, one on each of them. Please make sure this additive camera and any other gameObject should have this component disabled.
Also at runtime, you can search which component(s) have AudioListener component attached using this in the Hierarchy window search bar.
t:AudioListener
This should help you out. Also double check using Debug.Log that OnControllerColliderHit function calls and Audio.clip is not null after assignment. Also is it necessary to play sound in Update ?
Also, you should move this line from Update to Start function instead, due to performance cost:
var Audio= gameObject.GetComponent(AudioSource);
and use this Audio variable throughout your script.

Resume music after exit app on windows phone

i`m using mediaElement to play background music in my app. And that works just fine.
Problem is when the user minimize the application. When the application resume there is no sound... I can play other sounds in my application but cant play that background music any more.
First i have this code to stop all background music at first time app open:
if (Microsoft.Xna.Framework.Media.MediaPlayer.State == MediaState.Playing)
{
Microsoft.Xna.Framework.Media.MediaPlayer.Pause();
FrameworkDispatcher.Update();
}
xaml code of that mediaElement
<MediaElement AutoPlay="True" Source="/Dodaci/pozadina.mp3" x:Name="muzika_pozadina" MediaEnded="pustiPonovo" Loaded="pustiPonovo" />
and the cs code
private void pustiPonovo(object sender, RoutedEventArgs e)
{
muzika_pozadina.Play();
}
sound is about 300kb size.
So, how can i resume that sound playing after the user resume the application?
When your App is put into Dormant State (when you hit Start buton for example), the MediaElement is stopped. Then after you return to your App (and it wasn't Tombstoned), the Page is not Initialized once again, which means that your MediaElement is not loaded once again, so your Music doesn't start once again.
It depends on your purpose and code how it can be returned. In very simple example when you don't need to remember music last position you can just set source of your MediaElement once again in OnNavigatedTo() event:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (e.NavigationMode == NavigationMode.Back)
muzika_pozadina.Source = new Uri("/Dodaci/pozadina.mp3", UriKind.RelativeOrAbsolute);
}
As you have set your MediaElement.AutoPlay to true - it should start automatically (because of that you probably also don't need your Loaded event pustiPonovo).
In more complicated cases you can take an advantage of Activation and Deactivation events of your App - returning to MediaElement from Dormant/Tombstoned case is well explained here in the article.
You should also read about Fast App Resume in case User decides to return to your App by Tile instead of Launchers-Choosers.
I haven't tried above code, but hopefully it will do the job.

IMFMediaPlayer hangs during SetSourceFromByteStream

Background: I'm coding a metro-styled app for Win8. I need to be able to play music-file. Because of quality and space requirements we're using encoded audio (mp3/ogg).
I'm using XAudio2 to play sound effects (.wav files), but since I couldn't figure out a way to play encoded audio with it, I decided to play the music files with Media Foundation (IMFMediaPlayer interface).
I downloaded metro apps sample, and found out that the Media Engine Native C++ video playback sample was closest to what I needed.
Now that my app has MediaPlayer playing musics, I ran into a problem. If the device running the app is slow enough, MediaPlayer hangs. When I'm running the release-version of the app on my device, it's fine and I can hear the music just fine. But when I attach the debugger or run it on a slower device, it hangs when I'm setting bytestream for the MediaPlayer to play.
Here's some code, you'll find it pretty similiar to the sample:
StorageFolder^ installedLocation = Windows::ApplicationModel::Package::Current->InstalledLocation;
m_pickFileTask = Concurrency::task<StorageFile^>(installedLocation->GetFileAsync(filename)), m_tcs.get_token());
auto player = this;
m_pickFileTask.then([player](StorageFile^ fileHandle)
{
player->SetURL(fileHandle->Path);
Concurrency::task<IRandomAccessStream^> fOpenStreamTask = Concurrency::task<IRandomAccessStream^> (fileHandle->OpenAsync(Windows::Storage::FileAccessMode::Read));
fOpenStreamTask.then([player](IRandomAccessStream^ streamHandle)
{
MEDIA::ThrowIfFailed(
player->m_spMediaEngine->Pause()
);
MEDIA::GetMediaError(player->m_spMediaEngine);
player->SetBytestream(streamHandle);
if (player->m_spMediaEngine)
{
MEDIA::ThrowIfFailed(
player->m_spEngineEx->Play()
);
MEDIA::GetMediaError(player->m_spMediaEngine);
}
}
);
}
);
And here's the SetBytestream method:
SetBytestream(IRandomAccessStream^ streamHandle)
{
if(m_spMFByteStream != nullptr)
{
m_spMFByteStream->Close();
m_spMFByteStream = nullptr;
}
MEDIA::ThrowIfFailed(
MFCreateMFByteStreamOnStreamEx((IUnknown*)streamHandle, &m_spMFByteStream)
);
MEDIA::ThrowIfFailed(
m_spEngineEx->SetSourceFromByteStream(m_spMFByteStream.Get(), m_bstrURL)
);
MEDIA::GetMediaError(m_spEngineEx);
return;
}
The line where it hangs is:
m_spEngineEx->SetSourceFromByteStream(m_spMFByteStream.Get(), m_bstrURL)
When I'm debugging the app, I can press pause and see the stack. Well, not much of it, but atleast I can see it that it's indefinitely at
ntdll.dll!77b7f4dc()
Any ideas why my app would hang in such a way?
(OPTIONAL: If you know a better way to play mp3/ogg in a c++ metro-styled app, let me know)
Could not figure out why this is happening, but I managed to code a work-a-round:
IMFSourceReader can be used to decode MP3s and feed bytes into XAudio2SourceVoice.
XAudio2 audio stream effect sample contains good example how to do this.

Notification sound not playing in J2ME

I am working on a J2ME application.
I am using Nokia 6131 NFC phone. I am using NetBeans IDE.
I have 4 forms and I am playing some notification sounds for the user while filling the form.
The problem is sound goes off suddenly after 3 to 4 min and the only solution is to exit the application and again open it.
My Code
public void playSoundOK()
{
try
{
InputStream is = getClass().getResourceAsStream("/OK.wav");
Player player = Manager.createPlayer(is,"audio/X-wav");
player.realize();
player.prefetch();
player.start();
}
catch(Exception e)
{
e.printStackTrace();
}
}
Exception
at com.nokia.mid.impl.isa.mmedia.audio.AudioOutImpl.openSession(AudioOutImpl.java:206)
at com.nokia.mid.impl.isa.mmedia.MediaOut.openDataSession(MediaOut.java:282)
at com.nokia.mid.impl.isa.mmedia.MediaPlayer.doPrefetch(MediaPlayer.java:155)
at com.nokia.mid.impl.isa.amms.audio.AdvancedSampledPlayer.doPrefetch(+4)
at com.nokia.mid.impl.isa.mmedia.BasicPlayer.prefetch(BasicPlayer.java:409)
at org.ird.epi.ui.UtilityClass.playSoundOK(UtilityClass.java:139)
at org.ird.epi.ui.EnrollmentForm.targetDetected(+695)
at javax.microedition.contactless.DiscoveryManager.notifyTargetListeners(DiscoveryManager.java : 700)
at javax.microedition.contactless.DiscoveryManager.access$1200(DiscoveryManager.java:103)
at javax.microedition.contactless.DiscoveryManager$Discoverer.notifyIndication(DiscoveryManager.java:882)
at com.nokia.mid.impl.isa.io.protocol.external.nfc.isi.NFCConnectionHandler$IndicationNotifier.run(+67) javax.microedition.media.MediaException: AUD
I would advise you to split NFC and audio playback into 2 different threads.
It is typically a bad idea to call a method that should take some time to complete (like prefetch) from inside an API callback (like targetDetected) because it makes you rely on a particularly robust kind of internal threading model that may not actually exist in your phone's implementation of MIDP.
You should have one thread whose sole purpose is to play the sounds that your application can emit. Use the NFC callback to send a non-blocking command to play a sound (typically using synchronized access to a queue of commands). The audio playback thread can decide to ignore commands if they were issued at a time when it was busy playing a sound (no point in notifying the users of multiple simultaneous NFC contacts)
You should close your player. Add the following code to your method:
PlayerListener listener = new PlayerListener() {
public void playerUpdate(Player player, String event, Object eventData) {
if (PlayerListener.END_OF_MEDIA.equals(event)) {
player.close();
}
}
};
player.addPlayerListener(listener);

Resources