
Partager:
Enrico est un ancien membre de l'équipe Vonage. Il a travaillé en tant qu'ingénieur de solutions, aidant l'équipe de vente avec son expertise technique. Il est passionné par le cloud, les startups et les nouvelles technologies. Il est le cofondateur d'une startup WebRTC en Italie. En dehors du travail, il aime voyager et goûter autant d'aliments bizarres que possible.
Vidéo + IA : amélioration des flux vidéo grâce aux codes QR et au filigrane
Temps de lecture : 4 minutes
Cet article a été mis à jour en mai 2025
Introduction
À l'ère du numérique, l'amélioration des flux Video est devenue une pratique de plus en plus populaire, que ce soit pour la stratégie de marque, la publicité ou la fourniture d'informations supplémentaires de manière non intrusive. Cet article de blog vous explique comment ajouter des codes QR et des filigranes à un flux vidéo à l'aide de l'API Video de Vonage.
Pour ce faire, nous allons exploiter les capacités de l'API Media Processor. Cette API innovante permet de personnaliser les flux audio et vidéo en intégrant des transformateurs dans le flux. Une exploration détaillée de l'API et de ses utilisations potentielles suivra plus loin dans ce billet.
TL;DR : Si vous souhaitez passer directement au déploiement, vous pouvez trouver tout le code de l'application sur GitHub
Configuration du projet
Installer Node et npm
Copier le dépôt dépôt GitHub
Exécuter
npm installExécuter
npm run serve
API des processeurs de médias
La bibliothèque Vonage Media Processor, disponible via npm, est un outil puissant qui simplifie l'utilisation de l'API Insertable Streams pour la transformation des pistes vidéo et audio. Dans le cadre de ce billet de blog, nous n'utiliserons que les méthodes vidéo.
La bibliothèque présente deux classes principales :
MediaProcessor : Cette classe gère les transformateurs et s'accompagne d'une méthode
setTransformers()pour configurer les transformateurs.MediaProcessorConnector : Cette classe nécessite un objet MediaProcessor pour son constructeur et est responsable de la gestion des pistes d'entrée et de sortie. Alors que la mise en œuvre des pistes est prise en charge par le client Video JS de Vonage, vous n'avez qu'à fournir l'instance de MediaProcessorConnector. Vous pouvez trouver la documentation correspondante à l'adresse suivante https://developer.vonage.com/en/video/guides/media-processor/web
Passons maintenant à la création des processeurs vidéo pour le code QR et la fonction de filigrane.
Utilisation des codes QR
Les codes QR ont trouvé de nombreuses utilisations dans le monde réel. Ils peuvent contenir des données telles que des URL, du texte, etc., qui peuvent être scannées à l'aide de l'appareil photo d'un smartphone. Dans un flux vidéo, les codes QR peuvent être utilisés pour diverses raisons, comme la redirection de l'utilisateur vers une URL spécifique, l'affichage d'un texte spécifique à l'utilisateur, etc.
Imaginez que vous organisiez un webinaire et que vous souhaitiez partager des liens utiles avec vos spectateurs. En intégrant un code QR dans votre flux en direct, vous pouvez facilement diriger votre public vers ces liens, en leur fournissant une méthode simple et en temps réel pour accéder à un contenu pertinent.
Mise en œuvre technique
Nous générons des codes QR à l'aide d'un transformateur personnalisé. Pour générer le code QR, nous utilisons une bibliothèque tierce appelée QrCode. L'URL du code QR est saisie par l'utilisateur. Nous utilisons le qrCode transformateur de notre répertoire transformers pour créer et positionner le QR Code sur le flux Video. Vous pouvez personnaliser la position et la taille du code QR.
// file add-qr-code.js
_createQrCodeWithBorder() {
// --- Step 1: Generate the base QR code using the library ---
// Create a temporary container DIV (required by qrcode.js)
// This div is never added to the document.
let tempQrContainer = document.createElement('div');
// Generate the QR code *without* internal padding/border from the lib
new QRCode(tempQrContainer, {
text: this.text,
width: this.qrWidth, // Use the data area width
height: this.qrHeight, // Use the data area height
colorDark: this.colorDark,
colorLight: this.colorLight, // Background of QR code itself
correctLevel: QRCode.CorrectLevel.H, // Or choose appropriate level
});
// qrcode.js generates either a <canvas> or an <img> inside the div.
// Prefer canvas if available.
const originalQrCanvas = tempQrContainer.querySelector('canvas');
const originalQrImg = tempQrContainer.querySelector('img');
if (!originalQrCanvas && !originalQrImg) {
throw new Error('QRCode library did not generate canvas or img element.');
}
// --- Step 2: Create the final canvas with the border ---
const finalCanvas = new OffscreenCanvas(this.finalWidth, this.finalHeight);
const finalCtx = finalCanvas.getContext('2d');
if (!finalCtx) {
throw new Error('Unable to create final QR CanvasRenderingContext2D');
}
// --- Step 3: Draw the border (background) and the QR code ---
// Fill the entire final canvas with the border color (usually white)
finalCtx.fillStyle = this.colorLight; // Use colorLight for the border
finalCtx.fillRect(0, 0, this.finalWidth, this.finalHeight);
// Draw the generated QR code (canvas or img) onto the center of the final canvas
const drawX = this.borderSize;
const drawY = this.borderSize;
if (originalQrCanvas) {
finalCtx.drawImage(
originalQrCanvas,
drawX,
drawY,
this.qrWidth,
this.qrHeight
);
} else {
// If it generated an image, draw the image
finalCtx.drawImage(
originalQrImg,
drawX,
drawY,
this.qrWidth,
this.qrHeight
);
}
// No need for the temporary div anymore
tempQrContainer = null; // Let garbage collection handle it
console.log('QR Code with border generated successfully.');
return finalCanvas; // Return the canvas with the border
}
async transform(frame, controller) {
// Ensure QR code generation was successful
if (!this.qrCanvasWithBorder_) {
// If QR code failed, just pass the frame through unmodified
controller.enqueue(frame);
return;
}
// Resize internal canvas only if needed (slight optimization)
if (
this.canvas_.width !== frame.displayWidth ||
this.canvas_.height !== frame.displayHeight
) {
this.canvas_.width = frame.displayWidth;
this.canvas_.height = frame.displayHeight;
}
const timestamp = frame.timestamp;
// Draw the incoming video frame
this.ctx_.drawImage(frame, 0, 0);
frame.close(); // Close the original frame
// Draw the pre-generated QR code (with border) onto the video frame
// Use the finalWidth and finalHeight for drawing
this.ctx_.drawImage(
this.qrCanvasWithBorder_,
this.x, // Position defined in constructor
this.y, // Position defined in constructor
this.finalWidth, // Draw with full border width
this.finalHeight // Draw with full border height
);
// Enqueue the modified frame
controller.enqueue(
new VideoFrame(this.canvas_, { timestamp, alpha: 'discard' })
);
}
À partir de l'interface utilisateur, vous pouvez définir l'URL du code QR, la taille et la position du code QR dans le flux vidéo.
QR code transformer
Utilisation de filigranes
Les filigranes sont couramment utilisés pour marquer et protéger le contenu numérique. Dans le contexte de la diffusion de vidéos, un filigrane peut avoir plusieurs fonctions : il peut s'agir du logo d'une entreprise pour l'image de marque, d'un symbole de droit d'auteur pour la protection du contenu, ou de toute autre image d'ailleurs.
Mise en œuvre technique
Pour le filigrane, nous acceptons un fichier image de l'utilisateur en entrée. L'image sélectionnée est ensuite retournée horizontalement pour contrer l'effet miroir du flux vidéo. Le transformateur watermark de notre répertoire transformers positionne alors le filigrane sur le flux Video. Vous pouvez personnaliser la position du filigrane.
_computePosition(frame) {
if (this._position === "top-left") {
return { x: frame.displayWidth - 150, y: 0 };
} else if (this._position === "top-right") {
return { x: 0, y: 0 };
} else if (this._position === "bottom-left") {
return { x: frame.displayWidth - 150, y: frame.displayHeight - 150 };
} else if (this._position === "bottom-right") {
return { x: 0, y: frame.displayHeight - 150 };
}
return { x: 0, y: 0 };
}
async transform(frame, controller) {
this.canvas_.width = frame.displayWidth;
this.canvas_.height = frame.displayHeight;
const timestamp = frame.timestamp;
this.ctx_.drawImage(frame, 0, 0, frame.displayWidth, frame.displayHeight);
const { x, y } = this._computePosition(frame);
this.ctx_.drawImage(this._image, x, y, 100, 80);
frame.close();
controller.enqueue(
new VideoFrame(this.canvas_, { timestamp, alpha: "discard" })
);
}
Watermark transformer
Guide du code
Sur la page principale, nous commençons par importer les paquets requis et par initialiser l'éditeur de flux vidéo. Nous avons deux formulaires, un pour chaque fonctionnalité (code QR et filigrane). Le formulaire approprié est affiché en fonction de la sélection de l'utilisateur.
Dans la fonction applyQrCode nous récupérons les données de l'utilisateur pour le code QR (URL, taille et position), nous configurons le transformateur de code QR et nous l'appliquons au flux vidéo.
De même, dans la fonction applyWatermark nous prenons l'image téléchargée, l'ajustons si nécessaire (retournement horizontal), configurons le transformateur de filigrane et l'appliquons au flux vidéo.
Le bouton "Appliquer" appelle la fonction appropriée en fonction de l'option sélectionnée, et le bouton "Effacer" peut être utilisé pour supprimer toutes les transformations du flux vidéo.
QR code generator example
Watermark generator example
Conclusion
L'amélioration des flux Video par l'ajout de codes QR ou de filigranes est un moyen puissant d'accroître l'interactivité, d'ajouter de la valeur et de protéger le contenu. Avec l'API Video de Vonage et un peu de JavaScript, il est assez simple d'ajouter ces fonctions à un flux vidéo. J'espère que cet article de blog vous a été utile et je vous encourage à expérimenter différentes façons d'utiliser les transformations de flux vidéo pour améliorer vos projets.
Vous pouvez trouver le GitHub ici. Si vous avez des questions ou des commentaires, rejoignez-nous sur le Slack des développeurs de Vonage ou envoyez-nous un message sur Xet nous vous répondrons !
Partager:
Enrico est un ancien membre de l'équipe Vonage. Il a travaillé en tant qu'ingénieur de solutions, aidant l'équipe de vente avec son expertise technique. Il est passionné par le cloud, les startups et les nouvelles technologies. Il est le cofondateur d'une startup WebRTC en Italie. En dehors du travail, il aime voyager et goûter autant d'aliments bizarres que possible.