nginx配置参照
现在的问题是,推送的rtmp流(rtmp://)可以播放,但是flv流(http://开头的)一直在缓冲
推流的代码:
package com.ruoyi.hcnetsdk.utils;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.*;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
@Slf4j
public class VideoTransformer {
public PipedOutputStream writer;
public PipedInputStream reader;
public FFmpegFrameGrabber grabber;
public FFmpegFrameRecorder recorder;
public volatile boolean running = false;
public VideoTransformer() {
try {
writer = new PipedOutputStream();
reader = new PipedInputStream(writer);
grabber = new FFmpegFrameGrabber(reader);
grabber.setOption("analyzeduration", "15000000"); // 15s
grabber.setOption("probesize", "15000000"); // 150 MB
} catch (IOException e) {
log.error("VideoTransformer init error:\n" + e);
}
FFmpegLogCallback.set();
}
public void start(int hash) {
try {
running = true;
grabber.start();
recorder = new FFmpegFrameRecorder("rtmp://localhost:1935/hash/" + hash, grabber.getImageWidth(),
grabber.getImageHeight(), grabber.getAudioChannels());
recorder.setFormat("flv");
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
recorder.start();
// 开启线程处理回放回调函数的视频流
new Thread(this::processStream).start();
} catch (FFmpegFrameGrabber.Exception e) {
log.error("start grabber error:\t" + e.getMessage());
} catch (FFmpegFrameRecorder.Exception e) {
log.error("start recorder error:\t" + e.getMessage());
}
}
private void processStream() {
while (running) {
try {
Frame frame;
if ((frame = grabber.grab()) != null) {
recorder.record(frame);
} else {
Thread.sleep(40);
}
} catch (InterruptedException e) {
log.error("processStream -> Thread.sleep error:\t" + e.getMessage());
} catch (FFmpegFrameGrabber.Exception e) {
log.error("Grabber error:\t" + e.getMessage());
} catch (FFmpegFrameRecorder.Exception e) {
log.error("Recorder error:\t" + e.getMessage());
}
}
this.cleanup();
log.info("VideoTransformer stopped");
}
/**
* stop the transformer
*/
public void stop() {
running = false;
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
log.error("停止播放回放视频:\t" + e.getMessage());
}
}
/**
* write bytes to the writer
*
* @param bytes the bytes to write
*/
public void write(byte[] bytes) {
try {
writer.write(bytes);
} catch (IOException e) {
log.error("writer write error", e);
}
log.info("write bytes to writer:\t" + bytes.length + " 字节");
}
/**
* release all resources, except for the writer
*/
private void cleanup() {
try {
if (recorder != null) {
recorder.stop();
recorder.close();
recorder.release();
}
} catch (FFmpegFrameRecorder.Exception e) {
log.error("recorder release error" + e.getMessage());
} catch (FrameRecorder.Exception e) {
log.error("recorder close error" + e.getMessage());
}
try {
if (grabber != null) {
grabber.stop();
grabber.close();
grabber.release();
}
} catch (FFmpegFrameGrabber.Exception e) {
log.error("grabber release error", e);
} catch (FrameGrabber.Exception e) {
log.error(grabber.getClass().getSimpleName() + " release error", e);
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
log.error("reader close error", e);
}
}
}
你用vlc拉一下flv的流看看能播吗?能播应该就是前端页面的问题,看前端的库是不是有问题。不能播应该就是转码的问题,用ffmpeg命令拉一下flv的流,看看报错。话说前端不是直接可以用rtmp嘛,就是延时会高一些。
前端可以播放吗? 我试了flvjs播不出来,vlc可以播rtmp链接
来自AI:
根据您的描述,我了解到您使用Java代码推送FLV流并通过Nginx进行播放,但FLV流一直在缓冲。这可能是由一些配置或代码问题引起的。我将提供一些可能解决问题的建议:
flv
模块。可以在http
或server
块中的modules
部分添加以下指令:load_module modules/ngx_http_flv_module.so;
location
块设置反向代理规则。例如,以下配置将代理请求到http://localhost:8080/your-flv-stream
:location /flv {
proxy_pass http://localhost:8080/your-flv-stream;
}
<video>
标签播放。<video>
标签中,确保视频源的URL与Nginx配置中设置的URL相对应。例如,如果您的Nginx配置为location /flv
,则视频源URL应为http://your-domain/flv
。不明白为什么套层java,flv 可以直接读nginx-flv 视频流的
Java推流到nginx,但是我试了,播不出来
@echo_lovely: 不明白你的流程。我搞过网页播放监控流。监控是rtmp,nginx接收监控流,提供flv流;网页播放器可以直接用flv流。你为啥用java推流到nginx;
@thirteenthree: 监控不是rtsp流吗?nginx可能我配置的有问题,转不出来flv流。而且我的流是录像机的流,不连续,所以就后台取流然后推流到nginx
采用了easymedia和easydrawin实现