最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - Encapsulation of raw opus frames to ogg using ffmpeg.autogen - Stack Overflow

programmeradmin4浏览0评论

I need to encapsulate raw opus frames ( from rtpdump similar format ), but i have trouble with function ffmpeg.avformat_write_header - Error writing opus headers -1094995529

public unsafe class OpusMuxer
{
    public static void ConvertRawOpusToOggOpus(string inputPath, string outputPath, int sampleRate = 48000, int channels = 2)
    {
        ffmpeg.av_log_set_level(ffmpeg.AV_LOG_INFO);
        AVOutputFormat* fmt = ffmpeg.av_guess_format("ogg", null, null);
        if (fmt == null)
        {
            Console.WriteLine("Nepodařilo se zjistit výstupní formát (ogg).");
            return;
        }

        AVFormatContext* oc = null;
        ffmpeg.avformat_alloc_output_context2(&oc, fmt, null, null);
        if (oc == null)
        {
            Console.WriteLine("Nepodařilo se vytvořit výstupní formátovací kontext.");
            return;
        }

        
        AVStream* st = ffmpeg.avformat_new_stream(oc, null);
        if (st == null)
        {
            Console.WriteLine("Nelze vytvořit nový stream.");
            goto cleanup;
        }

        AVCodecParameters* codecpar = st->codecpar;
        codecpar->codec_type = AVMediaType.AVMEDIA_TYPE_AUDIO;
        codecpar->codec_id = AVCodecID.AV_CODEC_ID_OPUS;
        codecpar->format = 8;//ffmpeg.AV_SAMPLE_FMT_FLTP;
        codecpar->sample_rate = sampleRate;
        ffmpeg.av_channel_layout_from_mask(&st->codecpar->ch_layout, ffmpeg.AV_CH_LAYOUT_STEREO);
        codecpar->ch_layout.nb_channels = channels;

        st->time_base = new AVRational { num = 1, den = codecpar->sample_rate };

        byte[] opusHeader = new byte[] {
        (byte)'O', (byte)'p', (byte)'u', (byte)'s', // Magic Signature "Opus"
        1, // Version
        2, // Channel count
        0, 0, // Pre-skip
        0x80, 0xBB, 0, 0, // Original sample rate (48000 Hz)
        0, // Gain
        0 // Channel mapping
        };

        codecpar->extradata = (byte*)ffmpeg.av_malloc((ulong)opusHeader.Length);
        Marshal.Copy(opusHeader, 0, (IntPtr)codecpar->extradata, opusHeader.Length);
        codecpar->extradata_size = opusHeader.Length;


     
        if ((fmt->flags & ffmpeg.AVFMT_NOFILE) == 0)
        {
            int ret = ffmpeg.avio_open(&oc->pb, outputPath, ffmpeg.AVIO_FLAG_WRITE);
            if (ret < 0)
            {
                Console.WriteLine("Nelze otevřít výstupní soubor.");
                goto cleanup;
            }
        }

        int re = ffmpeg.avformat_write_header(oc, null);
        if (re < 0)
        {
            goto cleanup;
        }

       
        using (var fs = File.OpenRead(inputPath))
        using (var br = new BinaryReader(fs))
        {
            while (br.BaseStream.Position < br.BaseStream.Length)
            {
                // Čteme délku framu (2 bajty)
                byte[] lengthBytes = br.ReadBytes(2);
                if (lengthBytes.Length < 2) break;

                int frameLen = lengthBytes[0] | (lengthBytes[1] << 8);
                if (frameLen <= 0 || frameLen > 65535) break;

                byte[] frameData = br.ReadBytes(frameLen);
                if (frameData.Length < frameLen) break;

                AVPacket pkt;
                ffmpeg.av_init_packet(&pkt);
                pkt.data = (byte*)ffmpeg.av_malloc((ulong)frameLen);
                Marshal.Copy(frameData, 0, (IntPtr)pkt.data, frameLen);
                pkt.size = frameLen;

                pkt.stream_index = st->index;

          
                int writeRet = ffmpeg.av_interleaved_write_frame(oc, &pkt);
                ffmpeg.av_free(pkt.data);

                if (writeRet < 0)
                {
                    Console.WriteLine("Chyba při zápisu framu.");
                    break;
                }
            }
        }

     
        ffmpeg.av_write_trailer(oc);

    cleanup:
        if (oc != null && oc->pb != null)
        {
            ffmpeg.avio_closep(&oc->pb);
        }
        if (oc != null)
        {
            ffmpeg.avformat_free_context(oc);
        }
    }
}
发布评论

评论列表(0)

  1. 暂无评论