Listen to all html video events - events

Playing around with html5 video and was wondering if there was a way to list its events as it happens.
I have one for ended - myVideo.addEventListener('ended',videoEnded,false);
Which works fine but how can i create a a listener which will listen to every event and name them?
myVideo.addEventListener('ALL',AddToLog,false);
function AddToLog(){
console.log(eventname);
}
Any pointers welcome.
Dan.

Subscribe to all <video> or <audio> events at once:
function addListenerMulti(el, s, fn) {
s.split(' ').forEach(e => el.addEventListener(e, fn, false));
}
var video = document.getElementById('myVideo');
addListenerMulti(video, 'abort canplay canplaythrough durationchange emptied encrypted ended error interruptbegin interruptend loadeddata loadedmetadata loadstart mozaudioavailable pause play playing progress ratechange seeked seeking stalled suspend timeupdate volumechange waiting', function(e){
console.log(e.type);
});
It's also a good idea to study media events list from the specification.
Multiple events listener credits go to #RobG's solution.

You can't. You need to listen to specific events.
You can find a list of possibly available events from the specification

Related

Is there a way to detect when a participant has muted their audio in opentok.js?

I went through the publisher docs which has the methods publishVideo(value) and publishAudio(value).
Corresponding to the video part, the subscriber receives the event videoDisabled or videoEnabled with the reason publishVideo which allows me to determine whether the subscribed participant has intentionally turned off their video or not, but I can't find something similar for audio such as audioDisabled or audioEnabled. audioBlocked event supposedly only covers blocks by browser's autoplay policy: Dispatched when the subscriber's audio is blocked because of the browser's autoplay policy.
The audioLevelUpdated event provides the current audio level, but that could just be silence, not an intentional mute, so that doesn't look ideal for this purpose.
I want to show a audio muted icon on the subscribed participants element when they have intentionally turned off their audio by calling publishAudio() method. How can that be achieved?
Referenced docs:
Subscriber events: https://tokbox.com/developer/sdks/js/reference/Subscriber.html#events
Publisher methods: https://tokbox.com/developer/sdks/js/reference/Publisher.html#methods
Each stream has an hasAudio attribute that returns false if the user's audio is muted or their microphone is muted. Similarly, streams also have a hasVideo attribute. You can reference the stream docs at https://tokbox.com/developer/sdks/js/reference/Stream.html.
I personally use it like so:
session.streams.forEach((stream) => {
const name = stream.name;
const video = stream.hasVideo;
const audio = stream.hasAudio;
});
You can listen for these changes with the session.on('streamPropertyChanged') event: https://tokbox.com/developer/sdks/js/reference/StreamPropertyChangedEvent.html
Hav u tried audioLevelUpdated and checking the level of audio
If level is 0 then its muted.
https://tokbox.com/developer/sdks/js/reference/Subscriber.html#getAudioVolume
So steps are listen audioLevelUpdated and check AudioVolume, audio volume should get u the subscriber level point.
Set OTSubscriberKitNetworkStatsDelegate to subscriber as
subscriber.networkStatsDelegate = self
Then you can call the below function to get simultaneous changes on subscribers' microphone status
func subscriber(_ subscriber: OTSubscriberKit, audioNetworkStatsUpdated stats: OTSubscriberKitAudioNetworkStats) {
// call stream.hasAudio
}
You can also check from opentok audioNetworkStatsUpdated

MacOS not responding to MPRemoteCommandCenter commands in the background

I am writing an application for my own purposes that aims to get play pause events no matter what is going on in the system. I have gotten this much working
let commandCenter = MPRemoteCommandCenter.shared()
commandCenter.togglePlayPauseCommand.isEnabled = true
commandCenter.togglePlayPauseCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
print("Play Pause Command")
return .success
}
commandCenter.nextTrackCommand.isEnabled = true
commandCenter.nextTrackCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
print("NextTrackCommand")
return .success
}
commandCenter.previousTrackCommand.isEnabled = true
commandCenter.previousTrackCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
print("previousTrackCommand")
return .success
}
commandCenter.playCommand.isEnabled = true
commandCenter.playCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
print("playCommand")
return .success
}
MPNowPlayingInfoCenter.default().playbackState = .playing
Most of those methods are there because apparently you will not get any notifications without having nextTrackCommand or previousTrackCommand or playCommand implemented.
Anyways my one issue is that as soon as you open another application that uses audio these event handlers stop getting called and I cant find a way to detect and fix this.
I would normally try doing AVAudioSession things to state this as a background application however that does not seem to work. Any ideas on how I can get playpause events no matter what state the system is in?
I would like to be able to always listen for these events OR get an indication of when someone else has taken control of the audio? Perhaps even be able to re-subscribe to these play pause events.
There's an internal queue in the system which contains all the audio event subscribers. Other applications get on top of it when you start using them.
I would like to be able to always listen for these events
There's no API for that but there's a dirty workaround. If I understand your issue correctly, this snippet:
MPNowPlayingInfoCenter.default().playbackState = .paused
MPNowPlayingInfoCenter.default().playbackState = .playing
must do the trick for you if you run it in a loop somewhere in your application.
Note that this is not 100% reliable because:
If an event is generated before two subsequent playbackState state changes right after you've switched to a different application, it would still be catched by the application in the active window;
If another application is doing the same thing, there would be a constant race condition in the queue, with unpredictable outcome.
References:
Documentation for playbackState is here;
See also a similar question;
See also a bug report for mpv with a similar
issue (a pre-MPRemoteCommandCenter one, but still very valuable)
OR get an indication of when someone else has taken control of the audio
As far as I know there's no public API for this in macOS.

Share screen and send audio with two publishers

I am trying to share screen and send audio at the same time, I have managed to follow the instructions of Adam Ullman from this link Opentok Screen Sharing with Audio but the sound is quite bad , it is heard doubled and with very poor quality.
I have asked the technical support of tokbox and they tell me that another option is to use the same person with two publishers (one for screen and another to share audio). The problem is that when I do this or share a screen or share the camera + microphone, how can I make the other person see the shared screen and listen to me?
Another option I have is: is there any way to improve the sound of setusermedia? or avoid duplicating sound?
I have the following code:
screenSharingPublisher = Promise.all ([
                        OT.getUserMedia ({
                            videoSource: 'screen'
                        }),
                        OT.getUserMedia ({
                            videoSource: null
                        })
                    ])
                        .then (([screenStream, micStream]) => {
                        return OT.initPublisher (null, {
                            videoSource: screenStream.getVideoTracks () [0],
                            audioSource: micStream.getAudioTracks () [0]
                        });
                });
                    screenSharingPublisher.then (publisher => {
                        l.publish (publisher, handleErrorScreen);
                }). catch (handleErrorScreen);
Thanks for your help
Tokbox QA staff here,
I think what you need is to create two publishers, one with just video (screensharing) and another one with audio and video (camera + microphone), against the same session. With that, other users subscribing to that sessionId would see your screen, and hear your voice.
If your sound is heard doubled, maybe you're publishing your microphone twice.
I hope this helps.

google-cast-sdk audio and subtitles manual handling on sender and receiver

we occurred an issue handling manually audio track and subtitles on sender web and mobile (v3 for both).
Basically, we are able to add some track info before load media, we found the added tracks on the receiver but there are present also the tracks that come from the manifest in two formats (AF and standard object).
There is a way to handle them once and to remove the original that comes from manifest on the receiver side?
Additionally, in this way, the senders will be notified of the change (eg. visible only audio track manually added)?
Many thanks for your support.
You can use message interception:
https://developers.google.com/cast/docs/caf_receiver_features#message-interception
Your interceptor should return the modified request or a Promise that resolves with the modified request value.
You can add your own tracks:
request.media.contentId = mediaUrl;
request.media.contentType = 'application/dash+xml';
request.media.tracks = [{
trackId: 1,
trackContentId: captionUrl,
trackContentType: 'text/vtt',
type: cast.framework.messages.TrackType.TEXT
}];

XCB event loop not getting any events

I am making an addon in Firefox, so I have a ChromeWorker - which is a privileged WebWorker. This is just a thread other then the mainthread.
In here I have no code but this (modified to make it look like not js-ctypes [which is the language for addons])
On startup I run this code, conn is a global variable:
conn = xcb_connect(null, null);
Then I run this in a 200ms interval:
evt = xcb_poll_for_event(conn);
console.log('evt:', evt);
if (!evt.isNull()) {
console.log('good got an event!!');
ostypes.API('free')(evt);
}
However evt is always null, I am never getting any events. My goal is to get all events on the system.
Anyone know what can cause something so simple to not work?
I have tried
xcb_change_window_attributes (conn, screens.data->root, XCB_CW_EVENT_MASK, values);
But this didn't fix it :(
The only way I can get it to work is by doing xcb_create_window xcb_map_window but then I get ONLY the events that happen in this created window.
You don't just magically get all events by opening a connection. There's only very few messages any client will receive, such as client messages, most others will only be sent to a client if it explicitly registered itself to receive them.
And yes, that means you have to register them on each and every window, which involves both crawling the tree and listening for windows being created, mapped, unmapped and destroyed and registering on them as well.
However, I would reconsider whether
My goal is to get all events on the system.
isn't an A-B problem. Why do you "need" all events? What do you actually want to do?

Resources