Embedder
Overview
The SourceSync Embedder is a powerful tool designed for developers to seamlessly integrate video content and other media types into their web applications. It offers flexible embedding strategies, including direct embedding, iframe integration, and advanced configurations for enhanced user experiences.
Features
- Flexible Embedding Strategies: Choose between direct embedding, iframe integration, or custom strategies to suit your application's needs.
- Dynamic Content Loading: Dynamically load and replace video content based on user interactions or other triggers.
- Customizable Player Controls: Tailor the video player's controls and appearance to match your site's design.
- Advanced Configuration Options: Utilize JSON configurations for detailed setup, including environment settings, distribution IDs, and embedding scopes.
- Cross-Browser Compatibility: Ensure consistent playback across all major browsers with built-in support for various video codecs.
Core Components
Constructors
- Embedder(settings): Constructs an instance of the Embedder with customizable settings. This allows the initialization of the embedder with specified configurations that dictate how embedding is to be performed.
Properties
- #resizeHandler: A private method that handles the resizing of embedded elements.
- context: Maintains a shared context across all embeds, ensuring consistency in settings and states.
- initialized: A boolean indicating whether the Embedder has been initialized, crucial for lifecycle management.
Methods
- #createContext(settings): Initializes a new EmbedderContext, central to managing the embed lifecycle and states.
- #embedElement(targetEl, embedSettings, embedTargetFactory): Handles the embedding of an element based on provided settings and target factory functions.
- #findTargetElements(embedSettings): Discovers and returns a promise of the elements to be targeted for embedding.
- #init(): Private method for internal initialization procedures.
- #loadSettings(elementSettings): Loads and applies settings for specific embed elements, allowing for dynamic configuration.
- #unwatchResize(): Stops the embedder from listening to resize events.
- #watchResize(): Enables the embedder to respond to resize events, adjusting embeds as necessary.
- destroy(): Cleans up and removes all embeds, useful for teardown processes in single-page applications.
- detectEmbedTargetsFromDom(opts): Identifies potential targets in the DOM for embedding based on options.
- embed(elementSettings): Commences the embedding process for elements, merging individual settings with global context settings.
- getRegisteredService(name): Retrieves a registered service by name, providing access to additional functionalities or extensions.
- hide(): Hides the embedded content, which can be useful for conditional displays or user interactions.
- registerService(...args): Registers a new service to the Embedder, enhancing its capabilities with additional features.
- show(): Reveals the embedded content, commonly used in conjunction with the
hide
method for toggling visibility. - unregisterService(...args): Removes a previously registered service, detaching its functionalities from the Embedder.
Integration Methods
1. Basic HTML5 Video Embedding
User Story: John, a developer at a small tech startup, wants to embed a simple HTML5 video on their landing page to showcase their new product. The goal is to have a lightweight and straightforward video player without external dependencies.
Code Example:
<head>
<script src="" />
</head>
<body>
<video id="basic-video" controls style="width: 100%;">
<source src="//path/to/video.mp4" type="video/mp4">
</video>
</body>
Why Use This Approach: Ideal for developers like John who need a simple and quick way to display video content without requiring advanced features or analytics.
2. Embedding with Video.js for Enhanced Controls
User Story: Emily, a front-end developer at an e-learning company, needs to provide students with an interactive video experience that includes custom controls, annotations, and quizzes within the video.
Code Example:
<head>
<link href="https://vjs.zencdn.net/7.19.2/video-js.css" rel="stylesheet" />
<script src="https://vjs.zencdn.net/7.19.2/video.min.js"></script>
<script src="" />
</head>
<body>
<video id="vjs_example" class="video-js" controls data-setup="{}">
<source src="//path/to/educational-video.mp4" type="video/mp4">
</video>
</body>
Why Use This Approach: For developers like Emily, integrating with Video.js offers extensive customization and interactive features beyond the native HTML5 video capabilities.
3. Advanced Embedding with SourceSync Embedder
User Story: Alex, a developer at a marketing agency, needs to embed videos that include custom overlays, analytics, and interactive content tailored to different marketing campaigns.
Code Example:
<script type="application/json" id="embedder-settings">
{
"env": "prod",
"strategy": "direct-with-iframe",
"selector": ".marketing-video",
"distributionId": "campaign-123"
}
</script>
<script src="//cdn.sourcesync.io/embed.min.js" defer></script>
Why Use This Approach: For complex requirements like Alex's, the SourceSync Embedder allows embedding videos with custom interactions, tracking, and conditional content, making it suitable for dynamic marketing campaigns.
4. Embedding YouTube Videos with Video.js
User Story: Sam, a web developer at a news portal, needs to integrate news clips and interviews hosted on YouTube within their articles, using a custom player that matches the portal's branding.
Code Example:
<video id="youtube-video" class="video-js" controls data-setup='{ "techOrder": ["youtube"], "sources": [{ "type": "video/youtube", "src": "https://www.youtube.com/watch?v=xjS6SftYQaQ"}] }'></video>
<script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-youtube/2.6.1/Youtube.min.js"></script>
Why Use This Approach: Sam can leverage the Video.js YouTube plugin to embed YouTube videos with a consistent look and feel that aligns with the news portal's branding, offering a seamless user experience.
Targeting specific elements
Let's say we have multiple video players on a page, and they have IDs following a pattern like video-player-1
, video-player-2
, etc. We want to target all of these elements using a single regex pattern.
First, we'll define our regex pattern that matches anything that starts with video-player-
followed by any number.
Example Embed Code:
<!-- Embedder Configuration Script -->
<script type="application/json" id="embedder-settings">
{
"env": "prod",
"strategy": "direct",
"selector": "regex-pattern",
"regex": "^video-player-\\d+$",
"distributionId": "specific-distribution-id",
"options": {
"autoplay": true,
"controls": true
}
}
</script>
<!-- Embedder Script Inclusion -->
<script src="https://cdn.sourcesync.io/embed.min.js" defer></script>
<!-- Target Video Player Elements -->
<div id="video-container">
<video id="video-player-1" controls>
<source src="path_to_video_1.mp4" type="video/mp4">
</video>
<video id="video-player-2" controls>
<source src="path_to_video_2.mp4" type="video/mp4">
</video>
<!-- More video players with similar ID patterns -->
</div>
In the above script tag, regex-pattern
is a placeholder where the actual regex pattern should be inserted. The regex
key in the JSON configuration holds the regex pattern we want to apply to target elements. This pattern is then used by the Embedder to find all matching elements in the DOM.
Implementation Explanation:
- The Embedder script is included in the HTML with the
defer
attribute, ensuring it does not execute until the document has finished parsing. - The configuration for the Embedder is defined in a JSON script block. The
env
sets the environment,strategy
sets the embedding strategy, anddistributionId
is the unique identifier for the media content distribution. - The key aspect here is the
"selector": "regex-pattern"
and"regex": "^video-player-\\d+$"
. This tells the Embedder to use a regular expression to identify the elements to target for embedding. - The regex pattern
^video-player-\\d+$
is designed to match anyid
that starts withvideo-player-
and ends with one or more digits. This would target all video players numbered sequentially as per the pattern. - The
options
object contains settings such asautoplay
andcontrols
which define the behavior of the video player once it is embedded.
Programmatic Embed
-
Code Example
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<script type="text/javascript" src="//cdn.embed.ly/player-0.1.0.min.js"></script>
<script type="text/javascript" src="%VITE_CDN_ROOT%/embed.min.js?env=stg"></script>
<body>
<p>
As soon as you select a new file, experience engine is instantiated.
</p>
<div>
<label for="file-input">Select Audio/Video File</label>
<input id="file-input" type="file" accept="audio/*, video/*">
</div>
<div id="content">
<div id="experience-wrapper" style="height:600px;width:800px">
<video id="experience-video" controls style="height:100%;width:100%"></video>
</div>
</div>
<script>
const fileInputEl = document.getElementById('file-input');
const videoEl = document.getElementById('experience-video');
let selectedFileUrl = null;
const selectedFile = {
url: null,
clear() {
videoEl.src = null
if (this.url) {
URL.revokeObjectURL(this.url)
this.url = null
}
},
set(file) {
this.url = URL.createObjectURL(file)
videoEl.src = this.url
}
}
fileInputEl.addEventListener('change', (ev) => {
selectedFile.clear()
if (fileInputEl.files.length === 0) return
const [file] = fileInputEl.files
selectedFile.set(file)
SourceEmbeds.register({
env: 'dev'
})
.embed({
selector: '#experience-video',
distributionId: 'overlay-test-2'
})
.then((embedders) => {
const embedder = embedders[0]
embedder.eventEmitter.on('playerjs.ready', () => {
embedder.playerjs.player.send({ method: 'getCurrentTime' }, value => { console.log(value) })
})
})
})
</script>
</body>
</html> -
Explanation of the Embedder Usage
External Scripts
<script type="text/javascript" src="//cdn.embed.ly/player-0.1.0.min.js"></script>
<script type="text/javascript" src="%VITE_CDN_ROOT%/embed.min.js?env=stg"></script>Here, two external scripts are included:
- The Embedly Player, which likely provides additional video player functionality or integrations.
- The SourceSync Embedder script, with the
env
query parameter set to 'stg' (staging environment). This script will enable the Embedder functionalities on the web page.
File Input for Media
<input id="file-input" type="file" accept="audio/*, video/*">
This input allows users to select audio or video files from their local filesystem, which will be used by the video player on the page.
Video Element
<video id="experience-video" controls style="height:100%;width:100%"></video>
A standard HTML5 video player is defined with
controls
enabled and styling to make it fill its container.Script for Dynamic File Loading and Embedding
const fileInputEl = document.getElementById('file-input');
const videoEl = document.getElementById('experience-video');
// ... Additional code for handling file selectionIn the script, we have a process defined for when the user selects a new file. It creates an object URL for the selected file and sets it as the source for the video element.
Embedder Initialization and Video Embedding
SourceEmbeds.register({
env: 'dev'
})
.embed({
selector: '#experience-video',
distributionId: 'overlay-test-2'
})
// ...Once a file is selected, the SourceSync Embedder is registered and then called to embed the video. This is done by targeting the video element with the selector
#experience-video
and using a specificdistributionId
. Theenv
is set to 'dev', indicating that this is likely a development setup.Player.js Event Handling
embedder.eventEmitter.on('playerjs.ready', () => {
embedder.playerjs.player.send({ method: 'getCurrentTime' }, value => { console.log(value) })
})After embedding, the code listens for the 'playerjs.ready' event, which indicates that the player is ready. It then sends a message to the player, using the Player.js API, to retrieve the current time of the video, demonstrating how to interact with the video player programmatically.
Summary of Implementation
In summary, when a user selects a video file, the SourceSync Embedder:
- Is initialized and targets the video element for embedding content.
- Listens for Player.js events to interact with the player.
- Uses the
embed
method to attach the selected video to the player with the givendistributionId
.
Why This Approach?
This approach is used for cases where the video content is dynamic and not known in advance, such as user-generated content. It allows developers to build applications that can handle media files selected by users at runtime, and then use the SourceSync Embedder to apply additional functionalities or overlays to the native video player.
The implementation provided offers a template for developers looking to create customizable video experiences, where users can upload and view their own content with enhanced features provided by the Embedder and external scripts like Embedly Player and Player.js.
How to add embedder from browser console
-
Code
script = document.createElement('script)
script.defer = true
script.src = 'https://embed.sourcesync.io?el=.brid-small&env=dev&distributionId=56535&byUrl=true'
document.body.appendChild(script) -
Steps to add to the page
xyz
Page level embedder over-rides for testing/demo purposes. Example:
by adding
?StgbEE5LEe6j2Uu38haiJw=^
You can then specify json path dot notation in the query string args. You can actually test different versions of the embedder this way too.
?StgbEE5LEe6j2Uu38haiJw=^&version=1.10.11
Or change the env that we're loading distributions from:
?StgbEE5LEe6j2Uu38haiJw=^&env=stg&distributionId=whatever
Note that the unlock key is specified here: https://github.com/Source-Digital/embed/blob/main/packages/core/src/config.ts#L1C39-L1C61, and is subject to change.
Don't allow clients to depend on this.