Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <libavformat/avformat.h>
- #include <libavutil/samplefmt.h>
- #include <libavutil/opt.h>
- #include <libswresample/swresample.h>
- #include <string.h>
- #include <stdio.h>
- const char* get_str_err(const int err) {
- static char buf[1024];
- if (av_strerror(err, buf, sizeof(buf))) {
- strcpy(buf, "Couldn't get a proper error!");
- }
- return buf;
- }
- int main(int argc, char **argv) {
- int err;
- av_register_all();
- // setup format context
- AVFormatContext *fctx = NULL;
- if ((err = avformat_open_input(&fctx, argv[1], NULL, NULL)) < 0) {
- fprintf(stderr, "Couldn't open input: %s\n", get_str_err(err));
- return err;
- }
- if ((err = avformat_find_stream_info(fctx, NULL)) < 0) {
- fprintf(stderr, "Couldn't find stream info: %s\n", get_str_err(err));
- return err;
- }
- // find codec and stream ID
- AVCodec *decoder = NULL;
- int stream_id = av_find_best_stream(fctx, AVMEDIA_TYPE_AUDIO, -1, -1, &decoder, 0);
- if (stream_id < 0) {
- err = stream_id;
- fprintf(stderr, "Couldn't find best stream: %s\n", get_str_err(err));
- return err;
- }
- AVStream *stream = fctx->streams[stream_id];
- AVCodecContext *codec_ctx = stream->codec;
- // setup codec context
- if ((err = avcodec_open2(codec_ctx, decoder, NULL)) < 0) {
- fprintf(stderr, "Couldn't open codec: %s\n", get_str_err(err));
- return err;
- }
- // setup resampler
- int64_t dst_channel_layout = av_get_default_channel_layout(codec_ctx->channels);
- enum AVSampleFormat dst_sample_fmt = AV_SAMPLE_FMT_S16;
- int dst_sample_rate = 48000;
- int64_t src_channel_layout = codec_ctx->channel_layout;
- enum AVSampleFormat src_sample_fmt = codec_ctx->sample_fmt;
- int src_sample_rate = codec_ctx->sample_rate;
- SwrContext *resampler = swr_alloc_set_opts(NULL,
- dst_channel_layout,
- dst_sample_fmt,
- dst_sample_rate,
- src_channel_layout,
- src_sample_fmt,
- src_sample_rate,
- 0,
- NULL);
- if ((err = swr_init(resampler)) < 0) {
- fprintf(stderr, "Couldn't init resampler: %s\n", get_str_err(err));
- return err;
- }
- // allocate frames
- AVFrame *decoded = av_frame_alloc();
- AVFrame *encoded = av_frame_alloc();
- AVPacket packet;
- int got_frame = 0;
- int total_samples = 0;
- while (1) {
- if ((err = av_read_frame(fctx, &packet)) < 0) {break;}
- av_packet_rescale_ts(&packet, fctx->streams[stream_id]->time_base,
- codec_ctx->time_base);
- if (packet.stream_index != stream_id) {continue;}
- int total_length = 0;
- int len = avcodec_decode_audio4(codec_ctx, decoded, &got_frame, &packet);
- if (len == 0) {break;} //nothing left
- if (got_frame) {
- av_frame_set_sample_rate(encoded, dst_sample_rate);
- if (encoded->data[0] == NULL) {
- encoded->format = dst_sample_fmt;
- encoded->nb_samples = decoded->nb_samples;
- av_frame_set_channel_layout(encoded, dst_channel_layout);
- av_frame_get_buffer(encoded, 0);
- }
- if ((err = swr_convert_frame(resampler, encoded, decoded)) < 0) {
- fprintf(stderr, "Couldn't resample frame: %s\n", get_str_err(err));
- return err;
- }
- int data_size = av_samples_get_buffer_size(NULL, codec_ctx->channels, encoded->nb_samples, codec_ctx->sample_fmt, 1);
- fwrite(encoded->data[0], 1, data_size, stdout);
- total_samples += encoded->nb_samples;
- }
- }
- while (swr_get_delay(resampler, 1) > 0) {
- av_frame_set_sample_rate(encoded, dst_sample_rate);
- if (encoded->data[0] == NULL) {
- encoded->format = dst_sample_fmt;
- encoded->nb_samples = decoded->nb_samples;
- av_frame_set_channel_layout(encoded, dst_channel_layout);
- av_frame_get_buffer(encoded, 0);
- }
- if ((err = swr_convert_frame(resampler, encoded, NULL)) < 0) {
- fprintf(stderr, "Couldn't get frame from flushed resampler: %s\n", get_str_err(err));
- return err;
- }
- int data_size = av_samples_get_buffer_size(NULL, codec_ctx->channels, encoded->nb_samples, codec_ctx->sample_fmt, 1);
- fwrite(encoded->data[0], 1, data_size, stdout);
- total_samples += encoded->nb_samples;
- }
- fprintf(stderr, "Samples: %i\n", total_samples*2); //times 2 because nb_samples is per channel, and we have 2
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement