-
-
Save pisual/5f9943bced4baa213b185e6b4325c796 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.concurrent.Executors | |
import java.util.concurrent.TimeUnit | |
def UID = "276904" // B站用户UID | |
def ROOMID = "131985" // 直播间的房间编号,不是地址编号 | |
def OUTPUTDIR = /D:\Users\Sun\Desktop\ffmpeg\bin/ // 录制文件输出目录 | |
def FFMPEG = /D:\Users\Sun\Desktop\ffmpeg\bin\ffmpeg.exe/ // ffmpeg可执行程序位置 | |
def DELAY = 30 // SECONDS // 监控线程的间隔,当检测到直播时开启一个ffmpeg进程进行录制 | |
def scheduledExecutorService = Executors.newSingleThreadScheduledExecutor() | |
def counter = 0 | |
def isliving = false | |
def isrecording = false | |
Process process | |
scheduledExecutorService.scheduleWithFixedDelay({ | |
def islivingurl = new URL("http://live.bilibili.com/bili/isliving/$UID").text | |
isliving = !islivingurl.contains(/"data":""/) | |
if (isliving) { // 开始直播了 | |
if (!isrecording) { // 如果没有录制,则开始录制 | |
println "[${Calendar.getInstance().format("yyyy-MM-dd HH:mm:ss")}] 正在直播中" | |
println "[${Calendar.getInstance().format("yyyy-MM-dd HH:mm:ss")}] 开始录制了" | |
isrecording = true | |
Thread thread = new Thread({ // 开启一个守护线程去启动ffmpeg的进程防止阻塞监控线程 | |
def h5play = new URL("http://live.bilibili.com/api/h5playurl?roomid=$ROOMID").text | |
def matcher = h5play =~ /"url":"(.+)"/ | |
if (matcher.find()) { | |
def m3u8 = matcher.group(1) | |
String[] command = [FFMPEG, | |
"-i", "$m3u8", | |
"-acodec", "copy", | |
"-bsf:a", "aac_adtstoasc", | |
"-vcodec", "copy", | |
"-f", "mp4", | |
"${Calendar.getInstance().format("yyyy-MM-dd-HH-mm-ss")}.mp4"] | |
process = command.execute null, new File(OUTPUTDIR) | |
process.addShutdownHook { // 监听ctrl+c的事件,退出时发送q到ffmpeg进程,避免出现 moov atom not found 错误 | |
quitFFmpeg process | |
scheduledExecutorService.shutdown() | |
} | |
process.waitForProcessOutput System.out, System.err | |
} else { | |
println "[${Calendar.getInstance().format("yyyy-MM-dd HH:mm:ss")}] 无法获取直播流地址" | |
counter++ | |
if (counter == 10) { // 无法获取直播地址时,退出程序 | |
quitFFmpeg process | |
scheduledExecutorService.shutdown() | |
} | |
} | |
}) | |
thread.setDaemon(true) | |
thread.start() | |
} | |
} else { // 未检测到直播 | |
if (process == null || !process.alive) { // 如果当前没有ffmpeg的进程,则没有直播 | |
println "[${Calendar.getInstance().format("yyyy-MM-dd HH:mm:ss")}] 还没有直播" | |
} else { // 如果当前有ffmpeg的进程,发送q到ffmpeg使其退出 | |
println "[${Calendar.getInstance().format("yyyy-MM-dd HH:mm:ss")}] 直播关闭了" | |
quitFFmpeg process | |
isrecording = false | |
} | |
} | |
}, 0, DELAY, TimeUnit.SECONDS) | |
static void quitFFmpeg(Process process) { | |
if (process.alive) { | |
def writer = new BufferedWriter(new OutputStreamWriter(process.outputStream)) | |
writer.write("q") | |
writer.flush() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment