Implémenter plusieurs écrans de sortie vidéo dans les applications WPF¶
Video Capture SDK .Net Video Edit SDK .Net Media Player SDK .Net
Lors du développement d'applications WPF qui nécessitent de gérer plusieurs flux vidéo simultanément, les développeurs font souvent face à des défis de performance, de synchronisation et de gestion des ressources. Ce guide fournit une approche complète pour implémenter plusieurs écrans de sortie vidéo dans vos applications WPF en C# avec le contrôle Image.
Prise en main des plusieurs écrans vidéo¶
Consultez le guide d'installation pour WPF ici.
Pour commencer à implémenter plusieurs sorties vidéo dans votre application WPF, vous devrez :
- Ajouter le contrôle Video View approprié à votre application
- Configurer la gestion des événements pour le traitement des images vidéo
- Configurer votre pipeline de rendu pour des performances optimales
Deux modèles pris en charge¶
Pour afficher le même flux vidéo sur plusieurs vues dans WPF, choisissez l'un de ces deux modèles concrets :
MultiscreenVideoView+OnVideoFrameBuffer— un moteur SDK pousse chaque image dans autant de contrôlesMultiscreenVideoViewque vous le souhaitez. Utilisez ceci lorsqu'un seul moteur de capture/lecture pilote plusieurs copies à l'écran.- Un moteur par
VideoView— chaque affichage obtient sa propre instance deVideoCaptureCore/MediaPlayerCore/VideoEditCoreliée à son propreVideoViewstandard. Utilisez ceci lorsque les affichages montrent des sources différentes (par exemple une grille de sécurité à quatre caméras). Voir l'exemple Système de sécurité à quatre caméras ci-dessous.
Le VisioForge.Core.UI.WPF.VideoView standard n'expose pas de méthode RenderFrame — il est piloté automatiquement par le moteur auquel il est lié via CreateAsync(IVideoView). La distribution des images nécessite MultiscreenVideoView.
Configuration de votre projet WPF pour la distribution des images¶
Déposez un ou plusieurs contrôles VisioForge.Core.UI.WPF.MultiscreenVideoView sur votre fenêtre WPF. Donnez-leur des noms descriptifs (par exemple multiView1, multiView2). Ce sont les contrôles qui acceptent les images poussées.
Gestion des images vidéo¶
Abonnez-vous à l'événement OnVideoFrameBuffer du moteur SDK. Les arguments d'événement transportent un VideoFrameBufferEventArgs que chaque MultiscreenVideoView peut rendre.
Implémenter le gestionnaire d'images vidéo¶
private void VideoCapture1_OnVideoFrameBuffer(object sender, VideoFrameBufferEventArgs e)
{
multiView1.RenderFrame(e);
}
MultiscreenVideoView.RenderFrame(VideoFrameBufferEventArgs) copie l'image dans sa propre surface interne, donc le tampon du moteur peut être libéré lorsque le gestionnaire retourne.
Techniques d'implémentation avancées¶
Créer dynamiquement des MultiscreenVideoView¶
Pour les applications nécessitant un nombre variable de sorties vidéo, créez des contrôles MultiscreenVideoView dynamiquement :
private List<VisioForge.Core.UI.WPF.MultiscreenVideoView> multiViews =
new List<VisioForge.Core.UI.WPF.MultiscreenVideoView>();
private void CreateMultiView(Grid container, int row, int column)
{
var view = new VisioForge.Core.UI.WPF.MultiscreenVideoView();
Grid.SetRow(view, row);
Grid.SetColumn(view, column);
container.Children.Add(view);
multiViews.Add(view);
}
// Exemple d'utilisation :
// CreateMultiView(mainGrid, 0, 0);
// CreateMultiView(mainGrid, 0, 1);
Distribuer les images vidéo à plusieurs vues¶
Distribuez les images entrantes à chaque MultiscreenVideoView enregistré :
private void VideoCapture1_OnVideoFrameBuffer(object sender, VideoFrameBufferEventArgs e)
{
// Rendre vers toutes les instances MultiscreenVideoView
foreach (var view in multiViews)
{
view.RenderFrame(e);
}
}
Stratégies d'optimisation des performances¶
Réduire la charge de rendu¶
Pour plusieurs vues vidéo, envisagez ces techniques d'optimisation :
- Saut d'images : toutes les vues n'ont pas besoin de se mettre à jour à pleine fréquence
- Masquer les vues hors écran : WPF élimine le rendu des contrôles repliés — utilisez
Visibility.Collapsedsur les vues non visibles
private int frameCounter;
private void VideoCapture1_OnVideoFrameBuffer(object sender, VideoFrameBufferEventArgs e)
{
// La vue principale obtient toutes les images
primaryMultiView.RenderFrame(e);
// Les vues secondaires reçoivent une image sur deux
if (frameCounter % 2 == 0)
{
foreach (var view in secondaryMultiViews)
{
view.RenderFrame(e);
}
}
frameCounter++;
}
Exemple pratique : système de sécurité à quatre caméras¶
Voici un exemple plus complet d'implémentation d'un système de sécurité à quatre caméras avec le moteur VideoCaptureCore du Video Capture SDK. Chaque caméra obtient sa propre instance de moteur liée à un VideoView dédié.
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using VisioForge.Core.Types;
using VisioForge.Core.Types.VideoCapture;
using VisioForge.Core.UI.WPF;
using VisioForge.Core.VideoCapture;
public partial class SecurityMonitorWindow : Window
{
private readonly List<VideoView> _cameraViews = new List<VideoView>();
private readonly List<VideoCaptureCore> _cameras = new List<VideoCaptureCore>();
public SecurityMonitorWindow()
{
InitializeComponent();
}
public async Task InitializeCamerasAsync(IEnumerable<string> deviceNames)
{
// Énumérer les quatre premiers périphériques de capture si les noms ne sont pas fournis.
var names = deviceNames?.Take(4).ToList();
// Construire une grille 2x2 de contrôles VideoView associés à des moteurs VideoCaptureCore.
int i = 0;
for (int row = 0; row < 2; row++)
{
for (int col = 0; col < 2; col++, i++)
{
var view = new VideoView();
Grid.SetRow(view, row);
Grid.SetColumn(view, col);
mainGrid.Children.Add(view);
_cameraViews.Add(view);
// Le moteur classique utilise un constructeur ; CreateAsync est le modèle du moteur X.
// Pour VideoCaptureCoreX, utilisez `await VideoCaptureCoreX.CreateAsync(view)` à la place.
var camera = new VideoCaptureCore(view);
_cameras.Add(camera);
if (names != null && i < names.Count)
{
camera.Video_CaptureDevice = new VideoCaptureSource(names[i]);
camera.Video_CaptureDevice.Format_UseBest = true;
camera.Mode = VideoCaptureMode.VideoPreview;
camera.Audio_PlayAudio = false;
camera.Audio_RecordAudio = false;
}
}
}
}
public async Task StartCamerasAsync()
{
foreach (var camera in _cameras)
{
await camera.StartAsync();
}
}
public async Task StopCamerasAsync()
{
foreach (var camera in _cameras)
{
await camera.StopAsync();
}
foreach (var camera in _cameras)
{
camera.Dispose();
}
}
}
Énumérez les périphériques disponibles avec camera.Video_CaptureDevices() (ou sa variante asynchrone) pour renseigner l'argument deviceNames à l'exécution — voir le guide d'énumération des périphériques.
Dépannage des problèmes courants¶
Gérer la synchronisation des images¶
Si vous rencontrez des problèmes de minutage des images sur plusieurs affichages :
private readonly object syncLock = new object();
private void VideoCapture1_OnVideoFrameBuffer(object sender, VideoFrameBufferEventArgs e)
{
lock (syncLock)
{
foreach (var view in multiViews)
{
view.RenderFrame(e);
}
}
}
Pour plus d'exemples de code et de techniques d'implémentation avancées, visitez notre dépôt GitHub.