首页 新闻 会员 周边 捐助

nginx推flv流,然后前端页面播放

0
悬赏园豆:30 [已解决问题] 解决于 2024-08-15 09:04

nginx配置参照

  1. https://wxzzz.com/425.html
  2. https://wxzzz.com/443.html

现在的问题是,推送的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);
        }
    }
}
echo_lovely的主页 echo_lovely | 小虾三级 | 园豆:1584
提问于:2024-07-18 17:26
< >
分享
最佳答案
0

你用vlc拉一下flv的流看看能播吗?能播应该就是前端页面的问题,看前端的库是不是有问题。不能播应该就是转码的问题,用ffmpeg命令拉一下flv的流,看看报错。话说前端不是直接可以用rtmp嘛,就是延时会高一些。

收获园豆:15
孤独的伤逝 | 菜鸟二级 |园豆:217 | 2024-07-24 09:15

前端可以播放吗? 我试了flvjs播不出来,vlc可以播rtmp链接

echo_lovely | 园豆:1584 (小虾三级) | 2024-07-24 15:08
其他回答(3)
0

来自AI:

根据您的描述,我了解到您使用Java代码推送FLV流并通过Nginx进行播放,但FLV流一直在缓冲。这可能是由一些配置或代码问题引起的。我将提供一些可能解决问题的建议:

  1. 检查Nginx配置:
  • 确保您的Nginx配置文件中已启用flv模块。可以在httpserver块中的modules部分添加以下指令:
load_module modules/ngx_http_flv_module.so;
  • 确保您的Nginx配置正确反向代理到FLV流的URL。您可以使用location块设置反向代理规则。例如,以下配置将代理请求到http://localhost:8080/your-flv-stream
location /flv {
proxy_pass http://localhost:8080/your-flv-stream;
}
  1. 检查服务器端代码:
  • 确保通过Java代码推送的FLV流在网络环境中是可访问的,且符合FLV的格式和规范。
  • 检查通过Java代码推送FLV流的实现,确保没有任何异常抛出或错误发生。
  • 确保您使用的FFmpeg版本与您的代码和配置兼容。某些版本的FFmpeg和Nginx可能存在兼容性问题。
  1. 检查前端代码:
  • 确保您的前端代码正确处理FLV流,并使用HTML5的<video>标签播放。
  • <video>标签中,确保视频源的URL与Nginx配置中设置的URL相对应。例如,如果您的Nginx配置为location /flv,则视频源URL应为http://your-domain/flv
    请注意,这些是一般性建议,实际情况可能有所不同。在进行任何更改之前,强烈建议您备份相关文件和配置,并仔细阅读Nginx和FFmpeg的官方文档以获取更多详细信息和指导。如果问题仍然存在,您可能需要进一步调试或向相关社区或开发者寻求帮助。
收获园豆:7
Technologyforgood | 园豆:7775 (大侠五级) | 2024-07-24 21:46
0

不明白为什么套层java,flv 可以直接读nginx-flv 视频流的

收获园豆:8
thirteenthree | 园豆:216 (菜鸟二级) | 2024-08-02 11:23

Java推流到nginx,但是我试了,播不出来

支持(0) 反对(0) echo_lovely | 园豆:1584 (小虾三级) | 2024-08-02 13:12

@echo_lovely: 不明白你的流程。我搞过网页播放监控流。监控是rtmp,nginx接收监控流,提供flv流;网页播放器可以直接用flv流。你为啥用java推流到nginx;

支持(0) 反对(0) thirteenthree | 园豆:216 (菜鸟二级) | 2024-08-03 17:33

@thirteenthree: 监控不是rtsp流吗?nginx可能我配置的有问题,转不出来flv流。而且我的流是录像机的流,不连续,所以就后台取流然后推流到nginx

支持(0) 反对(0) echo_lovely | 园豆:1584 (小虾三级) | 2024-08-05 08:43
0

采用了easymedia和easydrawin实现

echo_lovely | 园豆:1584 (小虾三级) | 2024-08-15 09:03
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册