구글애드센스


[FFMPEG] how to dump rtsp/rtp stream to file STUDY



* How to dump file from RTSP/RTP Streaming data using ffmpeg.

  1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <stdio.h> 
#include <stdlib.h>
#include <unistd.h>

extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
#include <libavdevice/avdevice.h>
}

int
main (void)
{
avdevice_register_all();
av_register_all();
avcodec_register_all();
avformat_network_init();
// Initialize

int vidx = 0, aidx = 0; // Video, Audio Index
AVFormatContext* ctx = avformat_alloc_context();
AVDictionary *dicts = NULL;
AVFormatContext* oc = NULL;
avformat_alloc_output_context2(&oc, NULL, "mp4", NULL);

int rc = av_dict_set(&dicts, "rtsp_transport", "tcp", 0); // default udp. Set tcp interleaved mode
if (rc < 0)
{
return EXIT_FAILURE;
}

/*
rc = av_dict_set(&dicts, "stimeout", "1 * 1000 * 1000", 0);
if (rc < 0)
{
printf("errrrrrrr %d\n", rc);
return -1;
}
*/

//open rtsp
if (avformat_open_input(&ctx, "rtsp://211.189.132.118:4554/nbr-media/media.nmp?ch=T142",NULL, &dicts) != 0)
{
return EXIT_FAILURE;
}

// get context
if (avformat_find_stream_info(ctx, NULL) < 0)
{
return EXIT_FAILURE;
}

//search video stream , audio stream
for (int i = 0 ; i < ctx->nb_streams ; i++)
{
if (ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
vidx = i;
if (ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
aidx = i;
}

AVPacket packet;

//open output file
if (oc == NULL)
{
printf("failed\n");
return EXIT_FAILURE;
}

AVStream* vstream = NULL;
AVStream* astream = NULL;

vstream = avformat_new_stream(oc, ctx->streams[vidx]->codec->codec);
astream = avformat_new_stream(oc, ctx->streams[aidx]->codec->codec);

avcodec_copy_context(vstream->codec, ctx->streams[vidx]->codec);
vstream->time_base = (AVRational){1, 90000};
vstream->sample_aspect_ratio = ctx->streams[vidx]->codec->sample_aspect_ratio;

avcodec_copy_context(astream->codec, ctx->streams[aidx]->codec);
astream->time_base = (AVRational){1, 16000};

int cnt = 0;
long long nGap = 0;
long long nGap2 = 1;

av_read_play(ctx);//play RTSP

avio_open(&oc->pb, "./output.mkv", AVIO_FLAG_WRITE);
avformat_write_header(oc, NULL);

while (true)
{
av_init_packet(&packet);
int nRecvPacket = av_read_frame(ctx, &packet);

if (packet.stream_index == vidx) // video frame
{
vstream->id = vidx;
packet.pts = av_rescale_q(nGap, (AVRational){1, 10000}, oc->streams[packet.stream_index]->time_base);
nGap += 333;
cnt++;

}
else if (packet.stream_index == aidx) // audio frame
{
astream->id = aidx;
packet.pts = av_rescale_q(nGap2, (AVRational){1, 10000}, oc->streams[packet.stream_index]->time_base);
nGap2 += 666;
}

packet.dts = packet.pts;// generally, dts is same as pts. it only differ when the stream has b-frame
av_write_frame(oc,&packet);
av_packet_unref(&packet);

if (cnt > 300) // 10 sec
break;
}

av_read_pause(ctx);
av_write_trailer(oc);
avio_close(oc->pb);
avformat_free_context(oc);
av_dict_free(&dicts);

return (EXIT_SUCCESS);
}

ffmpeg 을 이용하여 RTSP 데이터를 수신, 파일로 덤프하는 예제코드.

https://github.com/JayShinMuzie/ProjLenaky/wiki/%5B%EB%B2%88%EC%99%B8%ED%8E%B8%5D-FFMPEG-::-RTSP-RTP-Receive-and-make-file



덧글

댓글 입력 영역