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); } |
덧글