Tools & Resources
Guides
Community
Video Embedding or Streaming Capabilities
Zesty.io can display video through 3rd party video services or self hosted videos uploaded to the media service.

Embedding Video from Youtube, Instagram and Vimeo

Standard embed codes provided by social media sites may be copy and pasted into a WYSIWYG Editor or directly into the content model HTML view file.
In youtube, click share, then click the embed option to get this view.
Web Developers can take advantage of parsley by adding a field to a content model called "youtube_id" (for example), and can make dynamic template views by using code like this:
1
<iframe width="560"
2
height="315"
3
src="https://www.youtube.com/embed/{{this.youtube_id}}"
4
frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
5
allowfullscreen>
6
</iframe>
Copied!

Streaming Video

For running your own stream, we suggest using a third party like Mux.com. A Mux stream can be put into any Zesty.io view, and a content model field and parsley can be used to give the Content Editor control of the stream id. In this example, we use the field name playback_id for the Mux stream ID
1
2
<video id="liveStream" autoplay controls height="900" width="1600"></video>
3
4
<!-- Use HLS.js to support the HLS format in browsers. -->
5
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
6
<script>
7
(function(){
8
// Replace with your asset's playback ID
9
var playbackId = "{{this.playback_id}}";
10
var url = "https://stream.mux.com/"+playbackId+".m3u8";
11
12
// HLS.js-specific setup code
13
if (Hls.isSupported()) {
14
var video = document.getElementById("liveStream");
15
var hls = new Hls();
16
hls.loadSource(url);
17
hls.attachMedia(video);
18
}
19
})();
20
</script>
Copied!

Video Conferencing

You can run your own video conferencing setup on Zesty.io using Vidyo (https://www.vidyo.com/), create an account. The setup requires view editing with javascript and an external server server call to issue a connection token.
View Code Example
1
2
<script>
3
function makeid(length) {
4
var result = "";
5
var characters =
6
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
7
var charactersLength = characters.length;
8
for (var i = 0; i < length; i++) {
9
result += characters.charAt(Math.floor(Math.random() * charactersLength));
10
}
11
return result;
12
}
13
14
// Add Vidyo Libray Callback
15
function onVidyoClientLoaded(status) {
16
switch (status.state) {
17
case "READY":
18
// Create Vidyoconnector
19
VC.CreateVidyoConnector({
20
viewId: null, //"renderer",
21
viewStyle: "VIDYO_CONNECTORVIEWSTYLE_Default",
22
remoteParticipants: 3,
23
logFileFilter: "warning [email protected] [email protected]",
24
logFileName: "",
25
userData: "",
26
}).then(function (vidyoConnector) {
27
//For acessing camera, microphone and speaker in chrome for latest vidyo library 4.1.24.15 register this device listener
28
vidyoConnector
29
.RegisterLocalCameraEventListener({
30
onAdded: function (localCamera) {
31
// New camera is available
32
},
33
onRemoved: function (localCamera) {
34
// Existing camera became unavailable
35
},
36
onSelected: function (localCamera) {
37
// Camera was selected/unselected by you or automatically
38
},
39
onStateUpdated: function (localCamera, state) {
40
// Camera state was updated
41
},
42
})
43
.then(function () {
44
console.log("RegisterLocalCameraEventListener Success");
45
})
46
.catch(function () {
47
console.error("RegisterLocalCameraEventListener Failed");
48
});
49
50
// Handle appearance and disappearance of microphone devices in the system
51
vidyoConnector
52
.RegisterLocalMicrophoneEventListener({
53
onAdded: function (localMicrophone) {
54
// New microphone is available
55
},
56
onRemoved: function (localMicrophone) {
57
// Existing microphone became unavailable
58
},
59
onSelected: function (localMicrophone) {
60
// Microphone was selected/unselected by you or automatically
61
},
62
onStateUpdated: function (localMicrophone, state) {
63
// Microphone state was updated
64
},
65
})
66
.then(function () {
67
console.log("RegisterLocalMicrophoneEventListener Success");
68
})
69
.catch(function () {
70
console.error("RegisterLocalMicrophoneEventListener Failed");
71
});
72
73
// Handle appearance and disappearance of speaker devices in the system
74
vidyoConnector
75
.RegisterLocalSpeakerEventListener({
76
onAdded: function (localSpeaker) {
77
// New speaker is available
78
},
79
onRemoved: function (localSpeaker) {
80
// Existing speaker became unavailable
81
},
82
onSelected: function (localSpeaker) {
83
// Speaker was selected/unselected by you or automatically
84
},
85
onStateUpdated: function (localSpeaker, state) {
86
// Speaker state was updated
87
},
88
})
89
.then(function () {
90
console.log("RegisterLocalSpeakerEventListener Success");
91
})
92
.catch(function () {
93
console.error("RegisterLocalSpeakerEventListener Failed");
94
});
95
96
97
let user = makeid(5);
98
99
let tokenEndpoint =
100
"https://XXXXX.cloudfunctions.net/vidyo-token-generator?userName=" +
101
user;
102
103
fetch(tokenEndpoint)
104
.then((response) => {
105
return response.json();
106
})
107
.then((data) => {
108
var token = data.token;
109
vidyoConnector.Connect({
110
host: "prod.vidyo.io",
111
token: token,
112
displayName: user,
113
resourceId: "testRoom", //Conference Name
114
onSuccess: function () {
115
console.log("Sucessfully connected");
116
},
117
onFailure: function (reason) {
118
console.log("Error while connecting ", reason);
119
},
120
onDisconnected: function (reason) {
121
console.log("Disconnected ", reason);
122
},
123
})
124
.then(function (status) {})
125
.catch(function () {});
126
});
127
});
128
break;
129
case "RETRYING":
130
console.log("Retrying");
131
break;
132
case "FAILED":
133
console.log("Failed");
134
break;
135
case "FAILEDVERSION":
136
console.log("Failed Version");
137
break;
138
case "NOTAVAILABLE":
139
console.log("Not Available");
140
break;
141
}
142
return true;
143
}
144
145
</script>
146
<div id="renderer" style="position: absolute; top: 50px; left: 0px; bottom: 0px; z-index: 99; height: 100%; width: 100%;"></div>
147
<script src="https://static.vidyo.io/latest/javascript/VidyoClient/VidyoClient.js?onload=onVidyoClientLoaded&webrtc=true&plugin=false"></script>
148
Copied!
GCP Cloud Function that issues a Token
1
exports.vidyoToken = (req, res) => {
2
const cors = require("cors")();
3
4
cors(req, res, () => {
5
exportVidyoToken(req, res);
6
});
7
};
8
9
const exportVidyoToken = async (req, res) => {
10
11
if (!req.hasOwnProperty('query') && !req.query.hasOwnProperty('userName')) {
12
return res.status(400).send("Error: expected userName param.");
13
}
14
15
jsSHA = require('jssha');
16
btoa = require('btoa');
17
fs = require('fs');
18
var tokenGenerated = false;
19
20
21
function generateToken(key, appID, userName, expiresInSeconds, vCard) {
22
var EPOCH_SECONDS = 62167219200;
23
var expires = Math.floor(Date.now() / 1000) + expiresInSeconds + EPOCH_SECONDS;
24
var shaObj = new jsSHA("SHA-384", "TEXT");
25
shaObj.setHMACKey(key, "TEXT");
26
jid = userName + '@' + appID;
27
var body = 'provision' + '\x00' + jid + '\x00' + expires + '\x00' + vCard;
28
shaObj.update(body);
29
var mac = shaObj.getHMAC("HEX");
30
var serialized = body + '\0' + mac;
31
return btoa(serialized);
32
}
33
34
let userName = req.query.userName
35
let expiresInSeconds = 99999;
36
let expiresAt = '';
37
let appID = process.env.APP_ID
38
let key = process.env.DEVELOPER_KEY
39
let vCard = ''
40
41
let token = generateToken(key, appID, userName, expiresInSeconds, "");
42
43
return res.status(200).json({
44
'token': token,
45
'user': userName
46
});
47
}
48
49
50
51
Copied!

WebRTC Options

Here is a list of 3rd party service options for peer to peer streaming through a website or mobile app.
  1. 1.
    Zoom - $100 for 4000 minutes ($0.025/minute)
    1. 1.
      Pros - Large-scale, reliable company with solid, proven tech, robust API
    2. 2.
      Cons - Expensive, lots of features, could potentially restrict content
  2. 2.
    Vidyo - $3000 for 250,000 minutes ($0.012/minute)
    1. 1.
      Pros - Simple html code to get started
    2. 2.
      Cons - Company is focused on medical, large-scale accounts, weak support
  3. 3.
    EasyRTC - Free if you host your own
    1. 1.
      Pros - Do it yourself, more control, free
    2. 2.
      Cons - Bare bones, no support
  4. 4.
    Twilio Video - $0.0015/minute for peer-to-peer, $0.01/minutes for room features
    1. 1.
      Pros - Great price for peer-to-peer only meaning you don’t get server-based room features
    2. 2.
      Cons - Only 10 people per room max, no group room features like recording, messaging, etc
  5. 5.
    AppRTC - Free, DIY
    1. 1.
      Pros - The ultimate bare bones, google sample app for WebRTC
    2. 2.
      Cons - Online demo had maybe 1- 1.5s delay, probably harder to implement
  6. 6.
    Agora.io - $2.50 per/1,000 minutes ($0.0025/minute) for 720p
    1. 1.
      Pros - No limit on rooms, inexpensive, lots of features such as broadcasting, solid codebase
    2. 2.
      Cons - Website not as enticing as Twilio but not bad either