diff --git a/README.md b/README.md index 74a0109..e7144ec 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This demo highlights [Daily's prebuilt UI](https://www.daily.co/blog/prebuilt-ui/), and how it can be used to embed a video chat widget in a website or app. The demo also illustrates how to use [daily-js methods](https://docs.daily.co/reference#instance-methods) and [events](https://docs.daily.co/reference#events) to build custom interfaces outside of the callframe that control the call. -Check out a live version of the demo [here](https://prebuilt-ui.netlify.app/). +Check out a live version of the demo [here](https://prebuilt-ui.netlify.app/). The demo's custom controls use these Daily methods: @@ -17,7 +17,8 @@ The demo's custom controls use these Daily methods: - [`.getNetworkStats()`](https://docs.daily.co/reference#%EF%B8%8F-getnetworkstats) - [`.setSubscribeToTracksAutomatically()`](https://docs.daily.co/reference#%EF%B8%8F-setsubscribetotracksautomatically) -![Video call takes up the left side of the screen, call controls on the right](./assets/prebuilt-ui-demo.gif) +![homescreen](./assets/homescreen.png) +![call ui](./assets/callui.png) ## Prerequisites @@ -34,24 +35,31 @@ Once a room has been created, the participant can click "Join call." This button 1. Install dependencies `npm i` 2. Start dev server `npm run dev` 3. Then open your browser and go to `http://localhost:8080` -4. Add your own room url in index.js and comment/uncomment the code as noted + +### To use live streaming: + +1. Create a Daily room through the [dashboard](https://dashboard.daily.co) or [REST API](https://docs.daily.co/reference/rest-api/rooms/create-room). +2. Create a [meeting token](https://docs.daily.co/reference/rest-api/meeting-tokens/create-meeting-token) for your new room with the [`is_owner` property](https://docs.daily.co/reference/rest-api/meeting-tokens/config#is_owner) set to `true`. +3. From the home screen, click "Enter my room URL" and use the room URL you create in step 1. + ![home screen with existing room URL](./assets/livestreaming.png) +4. Add your token from step 2 in `index.js` where the `.join()` call happens. There's a `todo` comment included to show you where to add it. + ![code where token should be added](./assets/token.png) OR... -## Running using Netlify CLI +## Running using Netlify CLI -If you want access to the Daily REST API (using the proxy as specified in `netlify.toml`) as well as a more robust local dev environment, please do the following (in this project's directory): +If you want access to the Daily REST API (using the proxy as specified in `netlify.toml`) as well as a more robust local dev environment, please do the following (in this project's directory): 1. Deploy to your Netlify account -[![Deploy with Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/daily-demos/prebuilt-ui) + [![Deploy with Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/daily-demos/prebuilt-ui) 2. Install the Netlify CLI `npm i -g netlify-cli` 3. Login to your account `netlify login` 4. Rename `sample.env` to `.env` and add your API key -4. Start the dev server `netlify dev` - -> Note: If the API proxy isn't working locally you may need to run `netlify build` first. This will put API key in the `netlify.toml` file, so make sure you don't commit this change. +5. Start the dev server `netlify dev` +> Note: If the API proxy isn't working locally you may need to run `netlify build` first. This will put API key in the `netlify.toml` file, so make sure you don't commit this change. ## Contributing and feedback diff --git a/assets/callui.png b/assets/callui.png new file mode 100644 index 0000000..9249518 Binary files /dev/null and b/assets/callui.png differ diff --git a/assets/homescreen.png b/assets/homescreen.png new file mode 100644 index 0000000..e1324c7 Binary files /dev/null and b/assets/homescreen.png differ diff --git a/assets/livestreaming.png b/assets/livestreaming.png new file mode 100644 index 0000000..95345fb Binary files /dev/null and b/assets/livestreaming.png differ diff --git a/assets/token.png b/assets/token.png new file mode 100644 index 0000000..919e73b Binary files /dev/null and b/assets/token.png differ diff --git a/index.css b/index.css index 1e2e14b..b8064b2 100644 --- a/index.css +++ b/index.css @@ -6,7 +6,7 @@ --dark-blue: #1f2d3d; --dark-blue-border: #2b3f56; --green: #72cc18; - --red-dark: #BB0C0C; + --red-dark: #bb0c0c; --font-family: GraphikRegular, 'Helvetica Neue', Sans-Serif; } @@ -102,7 +102,7 @@ body { } .white-button { - color: var(--dark-blue); + color: var(--dark-blue); display: flex; flex-direction: row; align-items: center; @@ -111,8 +111,8 @@ body { padding: 8px 16px; border-radius: 8px; flex: none; - font-size: 12px; - line-height: 16px; + font-size: 12px; + line-height: 16px; font-weight: bold; cursor: pointer; } @@ -286,7 +286,8 @@ body { cursor: pointer; } -.url-input { +.url-input, +.toast-input { width: 280px; height: 32px; padding: 8px 16px; @@ -313,21 +314,21 @@ body { } .error-message { - display: flex; - flex-direction: column; - align-items: center; + display: flex; + flex-direction: column; + align-items: center; } .error-title { - color: var(--red-dark); - font-size: 16px; - line-height: 24px; - margin: 0px; + color: var(--red-dark); + font-size: 16px; + line-height: 24px; + margin: 0px; } .error-description { - font-size: 12px; - line-height: 16px; + font-size: 12px; + line-height: 16px; padding: 0 16px; text-align: center; } @@ -366,3 +367,13 @@ body { width: 100%; } } + +form { + display: flex; + flex-direction: column; + padding-top: 16px; +} + +form div { + padding-top: 8px; +} diff --git a/index.html b/index.html index 35f5252..d53aba2 100644 --- a/index.html +++ b/index.html @@ -211,6 +211,43 @@

Example custom controls

+
+

Live streaming controls

+

+ You can also create your own meeting controls outside of the + callframe using daily-js. +

+
+ + + +
+
+ + +
+ +
+
+
diff --git a/index.js b/index.js index 37ac370..d85b455 100644 --- a/index.js +++ b/index.js @@ -113,6 +113,8 @@ async function joinCall() { await callFrame.join({ url: url, showLeaveButton: true, + //TODO: add an owner token to use live streaming + // token: , }); } catch (e) { if ( @@ -226,6 +228,86 @@ function toggleFullscreen() { callFrame.requestFullscreen(); } +// To use live streaming, the room URL should use the format: +// https://your-daily-domain.daily.co/room-name?t=your-owner-meeting-token +function startLiveStreaming() { + // This should be in the format rtmp://RTMP_ENDPOINT/STREAM_KEY + // or rtmps://RTMP_ENDPOINT/STREAM_KEY + console.log('starting!!!'); + const rtmpUrl = 'rtmp://RTMP_ENDPOINT/STREAM_KEY'; + callFrame.startLiveStreaming({ + rtmpUrl, + layout: { + preset: 'custom', + composition_params: { + 'videoSettings.showParticipantLabels': true, + }, + /* optional: sessions assets must be included in startLiveStreaming() even if they aren't used until an updateLiveStreaming() call + session asset images *must* be a .png + */ + session_assets: { + 'images/dailyLogo': 'https://docs.daily.co/assets/generic-meta.png', + }, + }, + }); +} + +function updateLiveStreaming() { + console.log('updating!!!'); + callFrame.updateLiveStreaming({ + layout: { + preset: 'custom', + composition_params: { + mode: 'pip', + showImageOverlay: true, + 'image.assetName': 'dailyLogo', + 'image.aspectRatio': 1, + 'image.position': 'bottom-left', + 'image.opacity': 0.7, + 'image.height_vh': 0.2, + 'image.margin_vh': 0.01, + showTextOverlay: true, + 'text.align_horizontal': 'right', + 'text.align_vertical': 'bottom', + 'text.offset_x': -20, + 'text.fontFamily': 'PermanentMarker', + 'text.content': 'Hello from Daily!', + }, + }, + }); +} + +function stopLiveStreaming() { + console.log('stopping!!!'); + callFrame.stopLiveStreaming(); +} + +let toastKey = 0; + +function showToast(e) { + // prevent default form behavior + e.preventDefault(); + // get input value from form submit event + const toastText = e.target[0].value; + + // send + callFrame.updateLiveStreaming({ + layout: { + preset: 'custom', + composition_params: { + 'toast.text': toastText, + 'toast.color': 'rgba(215, 50, 110, 0.8)', + 'toast.text.fontFamily': 'Bitter', + 'toast.duration_secs': 3, + 'toast.text.fontSize_pct': 150, + 'toast.text.fontWeight': '400', + 'toast.key': toastKey, + }, + }, + }); + toastKey++; +} + function toggleLocalVideo() { const localVideoButton = document.getElementById('local-video-button'); const currentlyShown = callFrame.showLocalVideo();