JAVA 解码rtsp视频流

18 篇文章 0 订阅
13 篇文章 0 订阅

package com.aast.test;


import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;


import org.bytedeco.javacpp.*;
import org.bytedeco.javacv.CanvasFrame;
import org.bytedeco.javacv.OpenCVFrameConverter;


//ffmpeg
import static org.bytedeco.javacpp.avcodec.*;
import static org.bytedeco.javacpp.avformat.*;
import static org.bytedeco.javacpp.avutil.*;
import static org.bytedeco.javacpp.swscale.*;
//opencv
import static  org.bytedeco.javacpp.opencv_core.* ;
import static org.bytedeco.javacpp.opencv_highgui.*;
import static  org.bytedeco.javacpp.opencv_imgcodecs.* ;
import static  org.bytedeco.javacpp.opencv_stitching.* ;
public class FFmpegTest {

public static void main(String[] args) throws IOException {
AVFormatContext pFormatCtx = new AVFormatContext(null);
int             i, videoStream;
AVCodecContext  pCodecCtx = null;
AVCodec         pCodec = null;
AVFrame         pFrame = null;
AVFrame         pFrameRGB = null;
AVPacket        packet = new AVPacket();
int[]           frameFinished = new int[1];
int             numBytes;
BytePointer     buffer = null;


AVDictionary    optionsDict = null;
SwsContext      sws_ctx = null;
av_register_all();
avformat_network_init();
// Register all formats and codecs
// String in="C:/img/video/m.h264";
String in="rtsp://admin:admin123@192.168.2.101:554/h264/ch1/main/av_stream";
// String in="rtmp://192.168.10.192/oflaDemo/stream live=1";
// String in="rtsp://123.124.159.5:554/pag://192.168.1.5:7302:81ef249ced3a454aaadda66a92697bf2:1:MAIN:TCP?cnid=4&pnid=5";
// Open video file
if (avformat_open_input(pFormatCtx, in, null, null) != 0) {
System.exit(-1); // Couldn't open file
}


// Retrieve stream information
if (avformat_find_stream_info(pFormatCtx, (PointerPointer)null) < 0) {
System.exit(-1); // Couldn't find stream information
}

// Dump information about file onto standard error
av_dump_format(pFormatCtx, 0, in, 0);

// Find the first video stream
videoStream = -1;
for (i = 0; i < pFormatCtx.nb_streams(); i++) {
if(pFormatCtx.streams(i).codecpar().codec_type()==AVMEDIA_TYPE_VIDEO){
videoStream = i;
break;
}
}
if (videoStream == -1) {
System.exit(-1); // Didn't find a video stream
}

// Get a pointer to the codec context for the video stream
pCodecCtx=avcodec_alloc_context3(null);
avcodec_parameters_to_context(pCodecCtx, pFormatCtx.streams(videoStream).codecpar());
// pCodecCtx = pFormatCtx.streams(videoStream).codec();


// Find the decoder for the video stream
pCodec = avcodec_find_decoder(pCodecCtx.codec_id());
if (pCodec == null) {
System.err.println("Unsupported codec!");
System.exit(-1); // Codec not found
}
// Open codec
if (avcodec_open2(pCodecCtx, pCodec, optionsDict) < 0) {
System.exit(-1); // Could not open codec
}


// Allocate video frame
pFrame = av_frame_alloc();


// Allocate an AVFrame structure
pFrameRGB = av_frame_alloc();
if(pFrameRGB == null) {
System.exit(-1);
}


// Determine required buffer size and allocate buffer
//        numBytes = avpicture_get_size(AV_PIX_FMT_RGB24,pCodecCtx.width(),pCodecCtx.height());
numBytes = av_image_get_buffer_size(AV_PIX_FMT_BGR24, 960, 540, 1); // 新版推荐替换函数
buffer = new BytePointer(av_malloc(numBytes));


sws_ctx = sws_getContext(pCodecCtx.width(), pCodecCtx.height(),pCodecCtx.pix_fmt(), 960,540,AV_PIX_FMT_BGR24, SWS_BILINEAR, null, null, (DoublePointer)null);
// sws_ctx = sws_getContext(pCodecCtx.width(), pCodecCtx.height(),pCodecCtx.pix_fmt(), pCodecCtx.width(), pCodecCtx.height(),AV_PIX_FMT_BGR24, SWS_BILINEAR, null, null, (DoublePointer)null);
// Assign appropriate parts of buffer to image planes in pFrameRGB
// Note that pFrameRGB is an AVFrame, but AVFrame is a superset
// of AVPicture
//        avpicture_fill(new AVPicture(pFrameRGB), buffer, AV_PIX_FMT_BGR24,pCodecCtx.width(), pCodecCtx.height());
av_image_fill_arrays(pFrameRGB.data(), pFrameRGB.linesize(), buffer, AV_PIX_FMT_BGR24, 960,540, 1); // 新版推荐替换函数


// Read frames and save first five frames to disk
i = 0;
//
av_dump_format(pFormatCtx, 0, in, 0);


Mat image=new Mat(540, 960,CV_8UC3);
// Mat image=new Mat(pCodecCtx.height(), pCodecCtx.width(),CV_8UC3);
while (av_read_frame(pFormatCtx, packet) >= 0) {
//pFormatCtx.fps_probe_size()
// Is this a packet from the video stream?
if (packet.stream_index() == videoStream) {
// Decode video frame
//                avcodec_decode_video2(pCodecCtx, pFrame, frameFinished, packet);
int result= avcodec_send_packet(pCodecCtx, packet);
if (result < 0) {
System.out.println("Decode Error1.");
return ;
}
result = avcodec_receive_frame(pCodecCtx, pFrame);
if (result < 0&&result!=-11){
System.out.println("Decode Error2.");
return ;
}
frameFinished[0]=1;
// System.out.println("显示时间戳:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(pFormatCtx.streams(0).cur_dts())));
// Did we get a video frame?
if (frameFinished[0] != 0) {
// Convert the image from its native format to RGB
sws_scale(sws_ctx, pFrame.data(), pFrame.linesize(), 0,pCodecCtx.height(), pFrameRGB.data(), pFrameRGB.linesize());


image.data(pFrameRGB.data(0));
imshow("haha", image);
if(waitKey(1)==27){
                break;
            }
// ShowImage(image);
// Save the frame to disk
//                    if (++i<=5) {
//                        SaveFrame(pFrameRGB, pCodecCtx.width(), pCodecCtx.height(), i);
//                    }
}
}


// Free the packet that was allocated by av_read_frame 
//            av_free_packet(packet);
av_packet_unref(packet); // 新版推荐替换函数
}


// Free the RGB image
av_free(buffer);
av_free(pFrameRGB);
// Free the YUV frame
av_free(pFrame);
// Close the codec
avcodec_close(pCodecCtx);
// Close the video file
avformat_close_input(pFormatCtx);
System.exit(0);
}
}
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
要实现RTSP(Real-Time Streaming Protocol)视频点播功能,可以使用Java语言结合第三方库来完成。 首先,需要选择一个适合的RTSP库,例如使用net.sf.fmj.media.rtsp包中的RTSPURLConnection类,它提供了RTSP连接和交互的功能。 在Java中,可以使用Socket类建立与RTSP服务器的TCP连接,并通过Socket的InputStream和OutputStream发送和接收RTSP请求和响应。可以借助RTSPURLConnection类来解析RTSP响应,以获取视频流信息。 接下来,需要发送RTSP SETUP请求,通过RTSP传输控制通道(RTSP-TCP)建立媒体通道,可以选择使用RTP协议或者TCP来传输视频数据。 然后,发送RTSP PLAY请求,开始播放视频。在获取到视频数据后,可以使用FFmpeg、VLCj等库来解码和播放视频。可以利用JavaFX或者Swing等图形库创建视频播放界面,并通过Java的多线程实现实时播放。 另外,为了提供更好的用户体验,可以在播放器中添加暂停、快进、快退等功能,需要发送相应的RTSP PAUSE、FAST FORWARD、REVERSE等请求来控制视频播放。 最后,当视频播放结束或用户手动停止播放时,需要发送RTSP TEARDOWN请求来关闭媒体通道,并断开与RTSP服务器的连接。 总结来说,通过选择适合的RTSP库,建立与RTSP服务器的TCP连接,发送RTSP请求并解析响应,以及使用第三方库来解码和播放视频,就可以实现JavaRTSP视频点播功能。
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值