Releases: daily-co/daily-js
0.34.0
Features
-
Added support for sending custom tracks in addition to camera, mic, and screen tracks.
If you were previously usingbeta*
methods to do this, you can migrate your code to use the new methods, which support sending custom tracks in peer-to-peer mode.
To start a custom track:const trackName = await callObject.startCustomTrack({ track }); // or, with all options specified... await callObject.startCustomTrack({ track, trackName: 'myGrooves', mode: 'music' });
To stop a custom track you’ve started:
callObject.stopCustomTrack(trackName);
You and other participants will receive track state updates via the normal
'participant-updated'
event. -
Added a
showUserNameChangeUI
call option for controlling whether to display the user name change UI in embedded Daily Prebuilt (true
by default). When set tofalse
, you should use tokens to assign participantsuser_name
s.const callObject = DailyIframe.createCallObject({ showUserNameChangeUI: false, });
-
Added a
maxDuration
option when starting a recording. The max recording duration is 3 hours if not specified. It is recommended you not touch this setting unless you’re planning on particularly long recorded meetings.callObject.startRecording({ maxDuration: 4 * 60 * 60 });
-
Pre-beta (early access customers only): Introduced a new meeting session data system, where you can set arbitrary data on a meeting that is synced to all participants. Some limits apply (see below, after code blocks).
To add data to a meeting:callObject.setMeetingSessionData({ foo: 'bar' }); // or, with all options specified... // replace the previous meeting session data with the new data (the default behavior) callObject.setMeetingSessionData({ foo: 'bar' }, 'replace'); // merge top-level keys in the new data on top of the previous data callObject.setMeetingSessionData({ foo: 'bar' }, 'shallow-merge');
To access meeting session data:
callObject.meetingSessionState().data;
To get notified when the meeting session data changed:
// note: this event actually fires when anything in meetingSessionState() // changes, which includes topology ('sfu' or 'peer') callObject.on('meeting-session-state-updated', (event) => { console.log(event.meetingSessionState.data); });
Please reach out to us if you'd like to discuss early access to this feature.
Limits:
- Data should be in the form of “plain” (map-like) JavaScript objects and should be JSON-serializable
- The rate of syncing data to clients is limited, so this system is not suited for highly real-time applications where sub-second interactions matter
- Data is limited in size, so this system is not suited for things like file-sharing
Bugfixes
- Fixed erroneously-reported track states for
rmpAudio
andrmpVideo
tracks when a remote media player was paused.
Now, after a pause:callObject.participants()['some-id'].tracks.rmpVideo.state; // 'off' callObject.participants()['some-id'].tracks.rmpVideo.off.byUser; // true
0.33.0
Features
- Added support for a customer-specified audio bitrate using the
micAudioMode
property. For example,dailyConfig: { micAudioMode: { bitrate: 256000, stereo: true } }
micAudioMode
can alternatively have the stringy values'speech'
or'music'
. Both fields in the object above are optional, and if not provided will default to the values shown, which is the same as having passed the string'music'
. For more information, see our audio mode config property docs.
- Added support for more transcription parameters. We now support the tier, detect_language, profanity_filter, and redact options. Here’s an example supplying all of our supported options as of this release:
let transcription = await callObject.startTranscription({ language: 'en', model: 'general', tier: 'base', detect_language: true, profanity_filter: false, redact: false, });
- All of the fields above are optional. If not provided, as of this release they default to the values shown above. For more information, see our transcription docs.
Bugfixes
- Fixed logging for errors encountered while sending RESTART_ICE messages to the SFU.
- Fixed an issue where a browser under high load may report a stale websocket when it is actually fine.
Other improvements
- Enhanced some limit enforcement boundaries within our SFUs to keep them healthier under high load situations.
- Overhauled the handling and normalizing of getUserMedia (gUM) errors.
0.32.0
Reminder
The code that daily-js downloads before you join a call is now “pinned” to this version of daily-js. That means you will no longer get unexpected updates to Daily client-side code without updating your daily-js dependency.
Read more about this change in 0.30.0's release notes.
Features
- Added support for specifying
startVideoOff
andstartAudioOff
as part of yourDailyCallOptions
(you could previously only do this by way of a token). In addition to giving you another way of controlling whether your camera and mic turn on automatically when youjoin()
a call, these properties enable a new scenario: you canstartCamera()
with one or both devices initially off without having firstpreAuth()
ed with a token.
Bugfixes
- Fixed a broken call to
console.warn()
- Fixed handling of default values for
enable_knocking
. - Fixed issue where
.destroy()
would never resolve when called inside of a left-meeting event handler, originally reported via github. Thanks for the report, @frankie567! - Fixed a potentially leaked background worker.
- Fixed a bug where recordings would not time out as expected.
Other improvements
- Began migration away from using
track
stats, because theRTCMediaStreamTrackStats
reports are being deprecated.
0.31.0
Features
-
A new permissions system allows you to specify a couple of different permissions for each participant:
canSend
, which specifies which kinds of media the participant is allowed to send ('video'
,'audio'
,'screenVideo'
,'screenAudio'
).hasPresence
, which specifies whether the participant appears as “present” (as opposed to “hidden”) in the meeting, i.e. whether they are listed in everyone’sparticipants()
.
Participant permissions can be specified in a couple of ways:
- Initial default permissions for new participants in your domain, room, or meeting token configurations
- A meeting owner can change other participants’ permissions at runtime with a call to
updateParticipant()
orupdateParticipants()
, e.g.updateParticipant('<participant-id>', { updatePermissions: { canSend: new Set(['video', 'audio']), hasPresence: true } })
-
The code that daily-js downloads before you join a call is now “pinned” to this version of daily-js. That means you will no longer get (in many cases, unwanted) updates to Daily client-side code without updating your daily-js dependency. Read more about this change in the last version’s release notes.
Bugfixes
- We fixed a bug where if you attempted to update your desired max spatial layer for some subscribed media (via
updateReceiveSettings({ '<participant-id>': { video: { layer: } } })
, say) while the subscription was still being established, the updated layer would never take effect. getNetworkTopology()
will now return the currently-chosen topology as soon as we know it, not after a delay.- We’ve stopped polluting your Sentry logs with our noisy breadcrumbs.
- If you
setUserData(null)
, other participants will see youruserData
change tonull
, notundefined
.
Other improvements
- Some optimizations to client-server signaling messages.
0.30.0
⚠ Notice: May require action
Dynamic updates to previous daily-js
versions will end
Today, if you're using daily-js
in call object mode, you may have noticed that certain bug fixes and updates are applied automatically to your client code, regardless of the version of daily-js
you're using. Sometimes, these dynamic updates can introduce slight changes to the behavior of the API.
We’ve received feedback from developers who are looking for more stability and want more control over when these fixes and updates end up in their client implementations.
So, starting in an upcoming version of daily-js
, bug fixes and updates will no longer be automatically applied to previous versions of daily-js
, reducing unexpected changes for users of our library.
Going forward, if you’re using a numbered version of daily-js
in call object mode, you will need to periodically update to the latest version in order to receive any of the latest fixes or improvements*.
If you're using daily-js
to embed Daily Prebuilt, there's no change; you'll continue to get the latest embedded Daily Prebuilt experience (though you might choose to regularly update daily-js
to take advantage of its latest API improvements*).
*Note: Daily commits to supporting previous daily-js
versions released up to 6 months ago, so you'll want to at least update to stay within that support window.
Features
-
🗣️ Experimental: User Data API
This preview of a new API is meant to allow customers to set and share custom participant state, like whether a participant in a call has raised their hand. The data is tied to a single participant, settable at join time, dynamically updatable, and retrievable remotely as data on each participant.
The data can be any JSON-serializable JavaScript object less than 4096 characters in length. It can be set via the new
userData
Frame property, or as a parameter to the new methodsetUserData
, and it can be read as a key on participant, e.g.participants()['local'].userData
.Note: this data is not intended for frequent, rapid updates. For example, it would not be ideal for storing real-time location of moving users within a spatial call application. Local state will be set immediately, and remote state will eventually reflect the last call made.
Full documentation for this feature will be released in the future as it matures.
-
🚀 Allow setting an idle timeout for streaming
When a user switches to another tab, some browsers throttle the CPU and cause their stream to pause. Idle timeout logic on our worker will stop livestreams or recordings automatically in this scenario, so we now allow users to override this behaviour and let streams run on for a configurable time before timing out as idle.
Control this behaviour by setting the new key
minIdleTimeOut
to a number of seconds in the DailyStreamingOptions object supplied to either thestartRecording
orstartLivestreaming
daily-js methods. For example:startRecording({ width: 1920, height: 1080, fps: 30, minIdleTimeOut: 5 * 60, // five minutes, the current default });
Bugfixes
- 🐛 Allow
joined_at
to be undefined, and prevent it from being set before it has a reasonable value. (Fixes Github issue #191).
Other Improvements
- 💻 Update streaming/recording APIs to allow specifying an
instanceId
. This lays the groundwork for some day enabling multiple active recordings and/or livestream instances per call. - 📷 Add new
selected-devices-updated
event which will fire whensetOutputDeviceAsync
is called, to allow applications to respond to output device changes.
0.29.0
Bugfixes
- Make it so you no longer have to do the strange
globalThis.regeneratorRuntime = undefined
workaround to avoid a CSP-unfriendly'unsafe-eval'
when you’re using Babel. See our guide on how to set up your Content Security Policy.
Other improvements
- Add TypeScript types for specifying custom video layout parameters in the
startRecording()
andstartLiveStreaming()
methods. - Pre-beta: Add TypeScript types to
DailyParticipant
facilitating handling a remote media player participant initiated withstartRemoteMediaPlayer()
. Specifically, addtracks.rmpVideo
,tracks.rmpAudio
, andparticipantType
(which will be'remote-media-player'
for remote media player participants). - Add an advanced (not generally recommended) configuration option,
callObjectBundleUrlOverride
, nested underdailyConfig
in theDailyIframe
properties. This makes it possible for you to, say, host the dynamically-downloaded call machine bundle yourself in order to have a stricter CSP. If the previous sentence doesn’t make a ton of sense to you, no sweat: ignore this configuration option! Again, it’s not recommended for most usage.
0.28.0
Features
- Adds
null
as a possible value foraudioDeviceId
andvideoDeviceId
insetInputDevicesAsync()
, which will result in keeping the current media track for that device. For example, passing in{audioDeviceId: “device_id”, videoDeviceId: null}
will get a new audio track but keep your current video track, allowing you to avoid a camera “blip”. - Adds a new
recordings_bucket
room and/or domain property to allow cloud recordings to be stored in a custom AWS S3 bucket. This allows HIPAA-enabled domains to use our cloud recording functionality. - Adds a
setOutputDeviceAsync()
method.setOutputDevice()
is now deprecated. This brings both device management functionssetInputDevicesAsync()
andsetOutputDeviceAsync()
to functional parity.
0.27.0
Features
- Added ability to add/remove rtmp endpoints for live streaming
- See the
endpoints
argument instartLiveStreaming
and the new methodsaddLiveStreamingEndpoints
andremoveLiveStreamingEndpoints
for more details.
- See the
- Added new
DailyAdvancedConfig
flag,noAutoDefaultDeviceChange
, to turn off the default behavior of automatically switching the device when the default device is selected and changes. - You can opt in to making daily-js behave in a CSP-friendly way by specifying
dailyConfig: { avoidEval: true }
wherever you provide your call options. If you do so, using daily-js will no longer require you to use'unsafe-eval'
in yourscript-src
directive. IMPORTANT: you will, however, have to specifyhttps://*.daily.co
in its place. - Transcription Improvements: Added the ability to set the language and model for transcriptions as well as introduced new ‘who done it’ fields in the transcription started/stopped events.
- See
startTranscription
for details on the new options available - See the new
startedBy
field intranscription-started
andupdatedBy
field intranscription-stopped
events
- See
- Added ability to configure high quality audio output when in SFU mode. See new fields in the
dailyConfig
object included in the frame propertiesmicAudioMode
: defaults tonull
. set tomusic
to increase the average bitrate of the microphone track to 256K.userMediaAudioConstraints
: allows you to pass in custom media track constraints for use in thegetUserMedia
call for the microphone track.
Bugfixes
- Fixed type information for
DailyStreamingEndpoint
Other improvements
- Added Hermes-compatible dev builds
- Add clearer error message for when caller uses unexpected key for custom button
0.26.0
Features
- Added support for setting the
fps
of a live stream through the live streaming options - Implemented new warnings messages and logs for when clients are on daily-js versions nearing end of support as well as error messages and logs for when they are on daily-js versions no longer supported.
- beta: When using
updateInputSettings()
to enablebackground-image
, allow data url types in lieu of http urls for the source image. - Introduced a new method and corresponding event for tracking the number of participants in a call (including the local participant). Previously, the best way to get at the participant count was to check the number of entries in
participants()
, but that list can take a little while to populate when first joining a call and will not include all the participants in future large meeting use cases.-
participantCounts()
: new function that returns an object containing the number ofpresent
andhidden
participants in the call.present
participants are ones that provide a presence—i.e. ones that are or will soon be in yourparticipants()
list.hidden
participants are participants that are participating in the call but not providing any presence—i.e. people passively watching a broadcast. Support for hidden participants will be coming soon.call.participantCounts(); // returns // { // present: <number of participants providing presence data> // hidden: <number of participants not providing presence data> // }
-
participant-counts-updated
: a new event to listen for which is emitted any time the participant counts change.call.on('participant-counts-updated', (e) => {}); // where e is: // { // action: 'participant-counts-updated' // participantCounts: { // present: <number of participants providing presence data> // hidden: <number of participants not providing presence data> // } // }
-
Bugfixes
- Fixed the check in the
room()
query so that it works and is available as soon as possible.
0.25.0
Features
- 📉 Added types for new packet loss fields,
totalSendPacketLoss
andtotalRecvPacketLoss
, in thegetNetworkStats()
response
Bugfixes
- 🐛 Prebuilt-only: Fixed issue where the Promise resolved too early on calls to
leave()
in iframe mode, causing issues for quick re-join()
s.
Other improvements
- 💀 Deprecated the optional
publish
flag in the input processor settings. - Prebuilt-only,
⚠️ Pre-Beta⚠️ : Implemented preliminary API for supporting custom buttons in the prebuilt UI.