Maison >cadre php >Workerman >Développement Workerman : Comment implémenter un système de diffusion vidéo en direct basé sur le protocole WebSocket

Développement Workerman : Comment implémenter un système de diffusion vidéo en direct basé sur le protocole WebSocket

WBOY
WBOYoriginal
2023-11-07 11:25:011199parcourir

Développement Workerman : Comment implémenter un système de diffusion vidéo en direct basé sur le protocole WebSocket

Workerman est un framework PHP haute performance qui peut atteindre des dizaines de millions de connexions simultanées via des E/S asynchrones non bloquantes. Il convient à la communication en temps réel, aux serveurs à haute concurrence et à d'autres scénarios. Dans cet article, nous présenterons comment utiliser le framework Workerman pour développer un système vidéo en direct basé sur le protocole WebSocket, y compris la création de services, la mise en œuvre du push et de la réception de flux vidéo en direct, l'affichage des pages frontales, etc.

1. Construisez le serveur

1. Installez le package de dépendances Workerman :

Exécutez la commande suivante pour installer le package de dépendances Workerman :

composer require workerman/workerman

2 Créez le serveur

Créez un fichier Workerman.php en tant que code de notre serveur. . Le code est le suivant :

<?php
use WorkermanWorker;
use WorkermanLibTimer;

require_once __DIR__ . '/vendor/autoload.php';

// 创建一个Worker监听2345端口,使用websocket协议通讯
$worker = new Worker("websocket://0.0.0.0:2345");

// 启动4个进程对外提供服务
$worker->count = 4;

// 客户端连接时触发
$worker->onConnect = function($connection) {
    echo "New client connected!
";
};

// 客户端请求时触发
$worker->onMessage = function($connection, $data) {
    if(strpos($data, 'start') === 0) {
        // 该客户端请求直播视频流
        $connection->send(getVideoStream());
        // 启动定时器,每秒向客户端发送一份视频流
        $timer_id = Timer::add(1, function()use($connection){
            $connection->send(getVideoStream());
        });
        // 将定时器ID绑定到连接上,方便后续停止定时器
        $connection->timer_id = $timer_id;
    }
    else if(strpos($data, 'stop') === 0) {
        // 该客户端停止请求直播视频流
        Timer::del($connection->timer_id);
    }
    else {
        // 其他请求,直接返回响应
        $connection->send("Hello, $data!");
    }
};

// 客户端断开连接时触发
$worker->onClose = function($connection) {
    // 清除定时器
    Timer::del($connection->timer_id);
    echo "Client disconnected!
";
};

// 以下是获取直播视频流的代码,可以替换为你自己的视频流获取代码
function getVideoStream() {
    $fp = fopen("videos/video.mp4", "rb");
    $chunk_size = 1024*1024; // 每次读取1MB
    $buffer = "";
    while(!feof($fp)) {
        $buffer .= fread($fp, $chunk_size);
        ob_flush();
        flush();
    }
    fclose($fp);
    return $buffer;
}

// 运行worker
Worker::runAll();

Dans le code ci-dessus, nous créons un objet Worker nommé worker et écoutons le port 2345 pour communiquer en utilisant le protocole websocket. Dans la fonction de rappel onMessage, si le client envoie un message « start », cela signifie que le client souhaite demander un flux vidéo en direct. Nous obtenons le flux vidéo via la fonction getVideoStream et utilisons une minuterie pour transmettre les données d'un flux vidéo au client chaque seconde. Si le client envoie un message "stop", cela signifie que le client arrête de demander le flux vidéo en direct, et nous fermons le timer correspondant à la connexion. D'autres requêtes renvoient directement des réponses.

2. Créer un fichier vidéo

Nous créons un dossier vidéos dans le répertoire racine et y ajoutons un fichier vidéo nommé video.mp4. Ce fichier vidéo peut être remplacé par votre propre flux vidéo en direct.

3. Démarrez le serveur

Allez dans le répertoire où se trouve Workerman.php sur la ligne de commande et exécutez la commande suivante pour démarrer le serveur :

php workerman.php start

Après un démarrage réussi, le serveur écoutera sur le port 2345 et pourra recevoir demandes du client. Demandé.

2. Implémentez le client

1. Introduisez socket.io et video.js

Nous utilisons deux bibliothèques, socket.io et video.js, pour implémenter les fonctions client. .

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Video live demo</title>
    <style>
        video {
            width: 800px;
            height: 600px;
        }
    </style>
</head>

<body>
    <h1>Video live demo</h1>
    <button id="start">Start live</button>
    <button id="stop">Stop live</button>
    <br/><br/>
    <video id="video-player" class="video-js vjs-default-skin"></video>

    <script src="https://cdn.bootcss.com/socket.io/3.1.3/socket.io.js"></script>
    <link href="https://cdn.bootcss.com/video.js/7.15.4/video-js.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/video.js/7.15.4/video.min.js"></script>
    <script>
        var socket = io('http://localhost:2345');
        var player = videojs('video-player');

        // 点击开始按钮,向服务端发起请求获取视频流
        document.querySelector('#start').addEventListener('click', function() {
            socket.send('start');
        });
        // 点击结束按钮,停止请求视频流
        document.querySelector('#stop').addEventListener('click', function() {
            socket.send('stop');
            player.pause();
        });
        // 收到服务端推送的视频流数据,开始播放视频
        socket.on('message', function(data) {
            player.src({ type: 'video/mp4', src: URL.createObjectURL(new Blob([data], { type: 'video/mp4' })) });
            player.play();
        });
    </script>
</body>
</html>

Dans le code ci-dessus, nous avons créé une page html simple comprenant un bouton de démarrage, un bouton de fin et un lecteur vidéo. Lorsque vous cliquez sur le bouton Démarrer, un message « Démarrer » est envoyé au serveur pour demander le flux vidéo. Lorsque vous cliquez sur le bouton de fin, un message « stop » est envoyé au serveur pour arrêter de demander le flux vidéo et mettre la lecture vidéo en pause. Lors de la réception des données du flux vidéo transmises par le serveur, nous utilisons la fonction URL.createObjectURL pour créer une URL de flux vidéo et transmettre l'URL au lecteur video.js pour la lecture.

2. Démarrez le client

Visitez la page html ci-dessus dans le navigateur et cliquez sur le bouton Démarrer pour lancer la lecture du flux vidéo en direct. Cliquez sur le bouton Arrêter pour arrêter de demander le flux vidéo et mettre la lecture vidéo en pause.

Résumé

En utilisant le framework Workerman et le protocole WebSocket, nous pouvons facilement mettre en œuvre un système de diffusion vidéo en direct hautes performances et à faible latence. Workerman fournit une prise en charge des E/S asynchrones non bloquantes et peut gérer rapidement des scénarios dans lesquels des millions de connexions sont accessibles simultanément, ce qui apporte une grande commodité aux communications en temps réel, aux serveurs à haute concurrence et à d'autres domaines. Dans cet article, nous utilisons les capacités de communication asynchrone de Workerman pour transmettre et recevoir des flux vidéo en temps réel entre le serveur et le client, rendant ainsi le système de diffusion en direct plus fluide et plus efficace.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn