ffmpeg直播加水印、拉流等任务

2024-02-09 01:32

本文主要是介绍ffmpeg直播加水印、拉流等任务,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 直播流加水印

ffmpeg -i  https://outbound-production.explore.org/stream-production-319/.m3u8  -vf "movie=black_water.png[watermark]; [in][watermark] overlay=main_w-overlay_w-20:main_h-overlay_h-10 [out]" -c:v libx264 -c:a copy -f flv "rtmp://livepush.gonature.cn/live/qwee?txSecret=39a51cfacc1d5d93216add5b5e0a017e&txTime=60DD7A3B"

 定时任务拉流并保存MP4文件

const ffmpeg = require('fluent-ffmpeg')
const config = require('./live_catch_tasks.json')
const fs = require('fs')
ffmpeg.setFfmpegPath('/usr/local/ffmpeg/bin/ffmpeg')  // /Users/bin/Downloads/ffmpeg 本机
const oneDay = 86400000
const tasks = {}  // 正在执行的任务
const checkAndRun = async function(){console.log('check and run task...', new Date())// 遍历任务列表for(let i in config.tasks){const task = config.tasks[i]const now = new Date()// 取当前时间,格式如 00:00 const time = ('0'+now.getHours()).slice(-2) + ':' + ('0'+now.getMinutes()).slice(-2)const exists = fs.existsSync(config.storeDir + task.saveAs)let overwrite = falseif(exists){const filestat = fs.statSync(config.storeDir + task.saveAs) // console.log('now:',now.getDay(),time,filestat.mtimeMs)if((now.getTime() - filestat.mtimeMs) > oneDay){overwrite = true}}// console.log(now.getDay() === task.weekDay,time >= task.startTime,(!exists || (exists && overwrite)))if(!tasks[task.name] && now.getDay() === task.weekDay  // 判断是否为当天任务&& time >= task.startTime                          // 判断是否已到任务开始时间&& (!exists || (exists && overwrite))){            // 判断文件是否已存在 或 上一次更新时间距现在是否大于24小时((t)=> {tasks[t.name] = {id: t.id,name: t.name,saveAs: t.saveAs,status: null}// 创建 ffmpeg 任务tasks[t.name].process = ffmpeg(task.source)// .videoBitrate(1000).addOptions(t.ffmpegOptions).on('error', function(err, stdout, stderr) {console.error('record live error: ' + err.message)tasks[t.name].status = 'Error'}).on("start", function (commandLine) {console.log(commandLine) tasks[t.name].status = 'Going'}).on("end", function () {// console.log('push over.') delete tasks[t.name]}).save(config.storeDir + t.saveAs)})(task)}}
}
// 格式化输出到控制台
function log(){const list = Object.values(tasks).map(i=>{return { id: i.id, name: i.name, status: i.status || '', saveAs: i.saveAs}})list.sort((a,b)=> a.id - b.id )console.table(list)
}
function run(){checkAndRun()                    // 首次立即执行setInterval(checkAndRun, 30000)  // 每 30 秒检查一次setInterval(log, 5000)           // 日志每 5 秒输出一次
}
run()/*
const cmd = ffmpeg('/Users/bin/Downloads/movies/心火/Firelight.1997.1080p.WEBRip.x264-RARBG.mp4')
// .duration(60)
// .loop(10)
// .seekInput(834.5) // set start time
.videoBitrate(1000)
// .noAudio()
.addOptions(['-vcodec copy','-acodec copy','-bsf:a aac_adtstoasc']
)
// .output('/Users/bin/Downloads/outputfile.mp4')
// .output('rtmp://livepush.gonature.cn/live/live1?txSecret=d6f5ab25a7f845391b7b58dd274ef19e&txTime=858C3C88')
.on('error', function(err, stdout, stderr) {console.log('Cannot process video: ' + err.message);
})
.on('end', function() {console.log('Processing finished !');
})
.format("flv")
.output('rtmp://livepush.gonature.cn/live/live1?txSecret=d6f5ab25a7f845391b7b58dd274ef19e&txTime=858C3C88', {end: true
})
.on("start", function (commandLine) {console.log("pushing......") //开始推流
})
.on("error", function (err, stdout, stderr) {console.log('push error:', err) //推流失败
})
.on("end", function () {console.log('push over.') //推流结束
});cmd.run();
//.save('/Users/bin/Downloads/outputfile.mp4');
*/

node方式拉流推流并加水印

 var ffmpeg = require('fluent-ffmpeg');const command = ffmpeg('https://outbound-production.explore.org/stream-production-319/.m3u8').videoFilters("movie=black_water.png[watermark]; [in][watermark] overlay=main_w-overlay_w-20:main_h-overlay_h-10 [out]").addOptions(["-vcodec libx264","-preset ultrafast","-acodec aac"]).format("flv").output('rtmp://livepush.gonature.cn/live/qwee?txSecret=39a51cfacc1d5d93216add5b5e0a017e&txTime=60DD7A3B', {end: true}).on("start", function (commandLine) {console.log("commandLine: " + commandLine);}).on("error", function (err, stdout, stderr) {console.log("commandLine: " + '失败');}).on("end", function () {});command.run()

使用process_argv传递参数,执行固定的ID之间的任务

启动方式:

node manage.js 1 3
任务id 1-3,包含1和3

const ffmpeg = require('fluent-ffmpeg')
const config = require('./live_push_tasks.json')
const fs = require('fs')
// ffmpeg.setFfmpegPath('/usr/local/ffmpeg/bin/ffmpeg')  // /Users/bin/Downloads/ffmpeg 本机
const oneDay = 86400000
const tasks = {}  // 正在执行的任务
let begin = 1 // 开始初始值
let end = 100 // 结束初始值
process.argv.forEach(function(val, index, array) {console.log(index + ': ' + val);if (index === 2) {begin = val}if (index === 3) {end = val}
});
const checkAndRun = async function(){console.log('check and run task...', new Date())// 遍历任务列表for(let i in config.tasks){const task = config.tasks[i]const now = new Date()// console.log(now.getDay() === task.weekDay,time >= task.startTime,(!exists || (exists && overwrite)))if(!tasks[task.name] && begin <=task.id && end>=task.id){            // 判断文件是否已存在 或 上一次更新时间距现在是否大于24小时((t)=> {tasks[t.name] = {id: t.id,name: t.name,saveAs: t.saveAs,status: null}// 创建 ffmpeg 任务tasks[t.name].process = ffmpeg('https://outbound-production.explore.org/stream-production-'+task.source+'/.m3u8').videoFilters("movie=black_water.png[watermark]; [in][watermark] overlay=main_w-overlay_w-20:main_h-overlay_h-10 [out]").addOptions(["-vcodec libx264","-preset ultrafast","-acodec aac"]).format("flv").output(task.output, {end: true}).on("start", function (commandLine) {console.log(commandLine)tasks[t.name].status = 'Going'}).on("error", function (err, stdout, stderr) {console.error('record live error: ' + err.message)tasks[t.name].status = 'Error'}).on("end", function () {delete tasks[t.name]}).run();})(task)}}
}
// 格式化输出到控制台
function log(){const list = Object.values(tasks).map(i=>{return { id: i.id, name: i.name, status: i.status || ''}})list.sort((a,b)=> a.id - b.id )console.table(list)
}
function run(){checkAndRun()                    // 首次立即执行setInterval(checkAndRun, 30000)  // 每 30 秒检查一次setInterval(log, 5000)           // 日志每 5 秒输出一次
}
run()

添加码率

const ffmpeg = require('fluent-ffmpeg')
const config = require('./live_push_tasks.json')
const fs = require('fs')
// ffmpeg.setFfmpegPath('/usr/local/ffmpeg/bin/ffmpeg')  // /Users/bin/Downloads/ffmpeg 本机
const oneDay = 86400000
const tasks = {}  // 正在执行的任务
let begin = 1 // 开始初始值
let end = 100 // 结束初始值
process.argv.forEach(function(val, index, array) {console.log(index + ': ' + val);if (index === 2) {begin = val}if (index === 3) {end = val}
});
const checkAndRun = async function(){console.log('check and run task...', new Date())// 遍历任务列表for(let i in config.tasks){const task = config.tasks[i]const now = new Date()// console.log(now.getDay() === task.weekDay,time >= task.startTime,(!exists || (exists && overwrite)))if(!tasks[task.name] && begin <=task.id && end>=task.id){            // 判断文件是否已存在 或 上一次更新时间距现在是否大于24小时((t)=> {tasks[t.name] = {id: t.id,name: t.name,saveAs: t.saveAs,status: null}// 创建 ffmpeg 任务tasks[t.name].process = ffmpeg('https://outbound-production.explore.org/stream-production-'+task.source+'/.m3u8').videoFilters("movie=black_water.png[watermark]; [in][watermark] overlay=main_w-overlay_w-20:main_h-overlay_h-10 [out]").addOptions(["-vcodec libx264","-preset ultrafast","-acodec aac","-video_size 1920x1080"]).videoBitrate('3072k').format("flv").output(task.output, {end: true}).on("start", function (commandLine) {console.log(commandLine)tasks[t.name].status = 'Going'}).on("error", function (err, stdout, stderr) {console.error('record live error: ' + err.message)tasks[t.name].status = 'Error'}).on("end", function () {delete tasks[t.name]}).run();})(task)}}
}
// 格式化输出到控制台
function log(){const list = Object.values(tasks).map(i=>{return { id: i.id, name: i.name, status: i.status || ''}})list.sort((a,b)=> a.id - b.id )console.table(list)
}
function run(){checkAndRun()                    // 首次立即执行setInterval(checkAndRun, 30000)  // 每 30 秒检查一次setInterval(log, 5000)           // 日志每 5 秒输出一次
}
run()

这篇关于ffmpeg直播加水印、拉流等任务的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/692773

相关文章

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

Spring定时任务只执行一次的原因分析与解决方案

《Spring定时任务只执行一次的原因分析与解决方案》在使用Spring的@Scheduled定时任务时,你是否遇到过任务只执行一次,后续不再触发的情况?这种情况可能由多种原因导致,如未启用调度、线程... 目录1. 问题背景2. Spring定时任务的基本用法3. 为什么定时任务只执行一次?3.1 未启用

如何使用Python实现一个简单的window任务管理器

《如何使用Python实现一个简单的window任务管理器》这篇文章主要为大家详细介绍了如何使用Python实现一个简单的window任务管理器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 任务管理器效果图完整代码import tkinter as tkfrom tkinter i

Spring Boot 集成 Quartz 使用Cron 表达式实现定时任务

《SpringBoot集成Quartz使用Cron表达式实现定时任务》本文介绍了如何在SpringBoot项目中集成Quartz并使用Cron表达式进行任务调度,通过添加Quartz依赖、创... 目录前言1. 添加 Quartz 依赖2. 创建 Quartz 任务3. 配置 Quartz 任务调度4. 启

Java使用多线程处理未知任务数的方案介绍

《Java使用多线程处理未知任务数的方案介绍》这篇文章主要为大家详细介绍了Java如何使用多线程实现处理未知任务数,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 知道任务个数,你可以定义好线程数规则,生成线程数去跑代码说明:1.虚拟线程池:使用 Executors.newVir

Spring Boot中定时任务Cron表达式的终极指南最佳实践记录

《SpringBoot中定时任务Cron表达式的终极指南最佳实践记录》本文详细介绍了SpringBoot中定时任务的实现方法,特别是Cron表达式的使用技巧和高级用法,从基础语法到复杂场景,从快速启... 目录一、Cron表达式基础1.1 Cron表达式结构1.2 核心语法规则二、Spring Boot中定

Spring Boot 整合 ShedLock 处理定时任务重复执行的问题小结

《SpringBoot整合ShedLock处理定时任务重复执行的问题小结》ShedLock是解决分布式系统中定时任务重复执行问题的Java库,通过在数据库中加锁,确保只有一个节点在指定时间执行... 目录前言什么是 ShedLock?ShedLock 的工作原理:定时任务重复执行China编程的问题使用 Shed

nginx-rtmp-module构建流媒体直播服务器实战指南

《nginx-rtmp-module构建流媒体直播服务器实战指南》本文主要介绍了nginx-rtmp-module构建流媒体直播服务器实战指南,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有... 目录1. RTMP协议介绍与应用RTMP协议的原理RTMP协议的应用RTMP与现代流媒体技术的关系2

Python Invoke自动化任务库的使用

《PythonInvoke自动化任务库的使用》Invoke是一个强大的Python库,用于编写自动化脚本,本文就来介绍一下PythonInvoke自动化任务库的使用,具有一定的参考价值,感兴趣的可以... 目录什么是 Invoke?如何安装 Invoke?Invoke 基础1. 运行测试2. 构建文档3.

解决Cron定时任务中Pytest脚本无法发送邮件的问题

《解决Cron定时任务中Pytest脚本无法发送邮件的问题》文章探讨解决在Cron定时任务中运行Pytest脚本时邮件发送失败的问题,先优化环境变量,再检查Pytest邮件配置,接着配置文件确保SMT... 目录引言1. 环境变量优化:确保Cron任务可以正确执行解决方案:1.1. 创建一个脚本1.2. 修