Mediasoup启动过程

一、启动server.js,调用createWorker方法创建进程

通过配置文件cpu数量创建worker,再createRouter,然后创建房间

server.js中
async function runMediasoupWorkers()
{
	const { numWorkers } = config.mediasoup;

	logger.info('running %d mediasoup Workers...', numWorkers);

	for (let i = 0; i < numWorkers; ++i)
	{
		const worker = await mediasoup.createWorker(
			{
				logLevel   : config.mediasoup.workerSettings.logLevel,
				logTags    : config.mediasoup.workerSettings.logTags,
				rtcMinPort : Number(config.mediasoup.workerSettings.rtcMinPort),
				rtcMaxPort : Number(config.mediasoup.workerSettings.rtcMaxPort)
			});

		worker.on('died', () =>
		{
			logger.error(
				'mediasoup Worker died, exiting  in 2 seconds... [pid:%d]', worker.pid);

			setTimeout(() => process.exit(1), 2000);
		});

		mediasoupWorkers.push(worker);

实例createRouter:

	static async create({ mediasoupWorker, roomId, consumerReplicas })
	{
		logger.info('create() [roomId:%s]', roomId);

		// Create a protoo Room instance.
		const protooRoom = new protoo.Room();

		// Router media codecs.
		const { mediaCodecs } = config.mediasoup.routerOptions;

		// Create a mediasoup Router.
		const mediasoupRouter = await mediasoupWorker.createRouter({ mediaCodecs });



Worker.js中
  async createRouter({ mediaCodecs, appData } = {}) {
        logger.debug('createRouter()');
        if (appData && typeof appData !== 'object') {
            throw new TypeError('if given, appData must be an object');
        }
        // This may throw.
        const rtpCapabilities = ortc.generateRouterRtpCapabilities(mediaCodecs);
        const reqData = { routerId: (0, uuid_1.v4)() };
        await this.#channel.request('worker.createRouter', undefined, reqData);
        const data = { rtpCapabilities };
        const router = new Router_1.Router({
            internal: {
                routerId: reqData.routerId
            },
            data,
            channel: this.#channel,
            payloadChannel: this.#payloadChannel,
            appData
        });
        this.#routers.add(router);
        router.on('@close', () => this.#routers.delete(router));
        // Emit observer event.
        this.#observer.safeEmit('newrouter', router);
        return router;
    }

二、创建父子进程,实现 js与c++进程交互的通道

  constructor({ logLevel, logTags, rtcMinPort, rtcMaxPort, dtlsCertificateFile, dtlsPrivateKeyFile, libwebrtcFieldTrials, bweAllowableNotifyThreshold, appData }) {
        super();
        logger.debug('constructor()');
        let spawnBin = workerBin;
        let spawnArgs = [];
        if (process.env.MEDIASOUP_USE_VALGRIND === 'true') {
            spawnBin = process.env.MEDIASOUP_VALGRIND_BIN || 'valgrind';
            if (process.env.MEDIASOUP_VALGRIND_OPTIONS) {
                spawnArgs = spawnArgs.concat(process.env.MEDIASOUP_VALGRIND_OPTIONS.split(/\s+/));
            }
            spawnArgs.push(workerBin);
        }

        this.#child = (0, child_process_1.spawn)(
        // command
        spawnBin, 
        // args
        spawnArgs, 
        // options
        {
            env: {
                MEDIASOUP_VERSION: '3.11.13',
                // Let the worker process inherit all environment variables, useful
                // if a custom and not in the path GCC is used so the user can set
                // LD_LIBRARY_PATH environment variable for runtime.
                ...process.env
            },
            detached: false,
            // fd 0 (stdin)   : Just ignore it.
            // fd 1 (stdout)  : Pipe it for 3rd libraries that log their own stuff.
            // fd 2 (stderr)  : Same as stdout.
            // fd 3 (channel) : Producer Channel fd.
            // fd 4 (channel) : Consumer Channel fd.
            // fd 5 (channel) : Producer PayloadChannel fd.
            // fd 6 (channel) : Consumer PayloadChannel fd.
            stdio: ['ignore', 'pipe', 'pipe', 'pipe', 'pipe', 'pipe', 'pipe'],
            windowsHide: true
        });
        this.#pid = this.#child.pid;
        this.#channel = new Channel_1.Channel({
            producerSocket: this.#child.stdio[3],
            consumerSocket: this.#child.stdio[4],
            pid: this.#pid
        });

worker.js构造函数中创建父子进程,通过socket可以实现 JavaScript 与 C++ 之间的相互收发消息
this._child = child_process_1.spawn(   spawnBin,    spawnArgs,  


使用 child_process.spawn() 方法创建了一个子进程,并将它赋值给 this.#child。spawn() 方法接受三个参数:

spawnBin:要执行的命令或可执行文件的路径。
spawnArgs:传递给命令的参数数组。
options:一个对象,用于配置子进程的选项。

options 对象中的一些重要配置包括:

env:指定子进程的环境变量。这里设置了 MEDIASOUP_VERSION 变量,并将父进程的环境变量继承给子进程。
detached:指定子进程是否独立运行,即与父进程无关。
stdio:指定子进程的标准输入、输出和错误流的处理方式。这里使用管道 (pipe) 来处理子进程的输出和错误。
windowsHide:在 Windows 系统中隐藏子进程的控制台窗口


 this.#channel = new Channel_1.Channel({
            producerSocket: this.#child.stdio[3],
            consumerSocket: this.#child.stdio[4],
            pid: this.#pid
        });

  await this.#channel.request('worker.createRouter', undefined, reqData);

 调用channel的request与C++进程通信

你可能感兴趣的:(音视频,java,前端,javascript)