Hooks de Scripting y Almacenamiento
plugNmeet ofrece potentes mecanismos de "hooks" tanto en los componentes del recorder (grabador) como del server (servidor) para permitir una personalización y automatización avanzadas de sus flujos de trabajo de medios. Un "script" puede ser cualquier archivo ejecutable (un script de shell, un programa de Go compilado, un script de NodeJS, etc.) que pueda leer desde stdin (entrada estándar) y escribir en stdout (salida estándar).
Grabador: Hooks de Scripting
Los hooks de scripting le permiten automatizar tareas en diferentes etapas del proceso de grabación y transcodificación. Esto es especialmente útil en una configuración de múltiples servidores donde la grabación y la transcodificación ocurren en máquinas diferentes.
Todos los scripts siguen una interfaz estándar: reciben una carga útil (payload) JSON a través de stdin y, opcionalmente, pueden devolver una carga útil JSON modificada a través de stdout. Si se definen múltiples scripts para un solo hook, forman una cadena (pipeline): el stdout del primer script se convierte en el stdin del segundo, y así sucesivamente.
Etapas de los Hooks
-
post_recording: Se ejecuta en el GRABADOR después de que se guarda el archivo sin procesar.- Propósito: Subir el archivo sin procesar a un almacenamiento compartido (NFS, S3, etc.).
- Acción: Debe devolver un JSON con la
file_path(ruta del archivo) actualizada a la nueva ubicación accesible por la red para el transcodificador.
-
pre_transcoding: Se ejecuta en el TRANSCODIFICADOR antes de queffmpegcomience.- Propósito: Descargar el archivo desde el almacenamiento compartido a una ruta local.
- Acción: Debe devolver un JSON con la
file_pathactualizada a la ruta local final para queffmpegla utilice.
-
post_transcoding: Se ejecuta en el TRANSCODIFICADOR después de queffmpegfinaliza.- Propósito: Limpieza final, notificación o subida del archivo procesado.
- Acción: Opcionalmente, puede devolver un JSON con la
file_pathactualizada (p. ej., a una URL de S3) para ser enviada al servidor principal de plugNmeet.
Configuración
Añada la ruta a su(s) ejecutable(s) en la sección hooks del archivo config.yaml de su grabador.
# config.yaml
hooks:
post_recording:
- "./scripts/post-recording/upload.sh"
pre_transcoding:
- "./scripts/pre-transcoding/download.sh"
post_transcoding:
- "./scripts/post-transcoding/upload-to-s3.sh"
- "./scripts/post-transcoding/notify-slack.sh"
Carga de Datos (stdin)
Su script recibirá un objeto JSON con la siguiente estructura:
{
"task": "single",
"recording_id": "REC_ax9s3djn2s",
"room_table_id": 123,
"room_id": "room01",
"room_sid": "SID_d82k3s9d2l",
"file_name": "REC_ax9s3djn2s.mp4",
"file_path": "/path/to/recording/files/node_01/room01/REC_ax9s3djn2s.mp4",
"file_paths": ["/path/to/segment1.mp4"],
"file_size": 123.45,
"recorder_id": "node_01"
}
Ejemplos de Scripts
Bash con jq
Este ejemplo lee la file_path desde stdin, la registra y pasa el JSON original a stdout.
#!/bin/bash
# scripts/post-recording/upload.sh
# Leer toda la entrada estándar
JSON_DATA=$(cat)
# Usar jq para extraer la file_path
FILE_PATH=$(echo $JSON_DATA | jq -r '.file_path')
# Registrar la acción (p. ej., en un archivo o en stderr)
echo "Subiendo archivo: $FILE_PATH" >&2
# Aquí, añadiría su lógica de subida (p. ej., aws s3 cp ...)
# Para este ejemplo, simplemente pasaremos los datos.
# Devolver el JSON original a stdout para el siguiente script en la cadena
echo $JSON_DATA
Node.js
Este ejemplo analiza los datos de stdin, registra el recording_id y devuelve un objeto JSON modificado a stdout.
#!/usr/bin/env node
// scripts/post-recording/upload.js
let data = '';
process.stdin.on('readable', () => {
let chunk;
while (null !== (chunk = process.stdin.read())) {
data += chunk;
}
});
process.stdin.on('end', () => {
if (!data) {
process.exit(0);
}
const scriptData = JSON.parse(data);
// Su lógica aquí
console.error(`Procesando grabación: ${scriptData.recording_id}`);
// Ejemplo: Modificar la file_path después de una subida
scriptData.file_path = `s3://mi-bucket/${scriptData.file_name}`;
// Enviar el JSON modificado a stdout
process.stdout.write(JSON.stringify(scriptData));
});
Servidor: Hooks de Almacenamiento
Los hooks de almacenamiento le permiten anular el almacenamiento de archivos local predeterminado e integrarse con cualquier proveedor de almacenamiento externo (p. ej., S3, Google Cloud Storage) mediante scripts personalizados. Esto es ideal para implementaciones nativas en la nube o de múltiples servidores donde necesita un almacenamiento centralizado y escalable.
Estos hooks se utilizan principalmente para los artefactos de sala. El upload_hook se activa cuando el servidor genera un artefacto. El download_hook y el delete_hook se utilizan tanto para artefactos como para grabaciones.
- Artefactos de Sala: Esto incluye tipos de artefactos como
MEETING_SUMMARY,SPEECH_TRANSCRIPTIONyMEETING_ANALYTICS. Para obtener una lista completa, consulte la definición oficial de protobuf. - Grabaciones: El servidor no utiliza el
upload_hookpara las grabaciones. En su lugar, el grabador debe subir la grabación final a su almacenamiento externo directamente a través de su hookpost_transcoding. Luego, el servidor utiliza eldownload_hooky eldelete_hookpara gestionar el acceso a esa grabación.
Si esta sección se omite en su config.yaml, el servidor almacenará todos los archivos en el disco local.
Configuración
Añada la sección storage_hooks al archivo config.yaml de su servidor.
# config.yaml
storage_hooks:
upload_hook:
- "./scripts/server_hooks/upload.sh"
download_hook:
- "./scripts/server_hooks/download.sh"
delete_hook:
- "./scripts/server_hooks/delete.sh"
Tipos de Hooks y Cargas Útiles (Payloads)
Hook de Subida (Upload Hook)
- Solicitud (
stdin) - Usado solo para artefactos.{"source_file_path": "/path/on/disk/analytics.json","service_type": "artifact","room_id": "room01","room_sid": "SID_d82k3s9d2l","room_table_id": 123} - Respuesta (
stdout): El script final debe devolver lalogical_path.{"logical_path": "artifacts/room01/analytics_SID_d82k3s9d2l.json","error": ""}
logical_path?La logical_path (ruta lógica) es un identificador único que su script de subida crea y entiende. Puede tener cualquier formato de cadena que elija, como una clave de objeto de S3 (mi-bucket/artifacts/file.json), un ID de archivo de un servicio de almacenamiento o un simple nombre de archivo. Este mismo valor se pasará más tarde a sus scripts download_hook y delete_hook, para que sepan sobre qué archivo actuar.
Hook de Descarga (Download Hook)
- Solicitud (
stdin):{"logical_path": "artifacts/room01/analytics_SID_d82k3s9d2l.json","service_type": "artifact"} - Respuesta (
stdout): El script final debe devolver unaaction(acción) y un valor correspondiente.{"action": "redirect","redirect_url": "https://s3.presigned.url/...","error": ""}
La action determina cómo el servidor proporcionará el archivo al usuario:
-
redirect(Recomendado): Su script debe devolver unaredirect_url. El servidor enviará una redirección307 Temporary Redirectal cliente, permitiéndole descargar el archivo directamente desde su almacenamiento externo. Esto es muy eficiente, ya que el archivo no pasa a través de su servidor. Un caso de uso común es generar una URL pre-firmada para un objeto de S3. -
serve_local: Su script primero debe descargar el archivo desde su almacenamiento externo a una ubicación temporal en el disco local del servidor. Luego, debe devolver lalocal_path(ruta local) completa y elmime_typecorrecto para el archivo (p. ej.,application/json,video/mp4). El servidor leerá el archivo desde esta ruta y lo transmitirá al cliente con la cabeceraContent-Typeadecuada. Este método consume más recursos del servidor y generalmente no se recomienda a menos que la redirección directa no sea posible.
Hook de Eliminación (Delete Hook)
- Solicitud (
stdin):{"logical_path": "artifacts/room01/analytics_SID_d82k3s9d2l.json","service_type": "artifact"} - Respuesta (
stdout): Opcional, para fines de registro.{"msg": "Archivo eliminado con éxito","error": ""}