sdcb / Sdcb.FFmpeg

FFmpeg basic .NET API generated by CppSharp
GNU Lesser General Public License v3.0
334 stars 53 forks source link

如何把图片连续帧转成视频推流出去 #20

Open sunkunGitHub opened 3 months ago

sunkunGitHub commented 3 months ago

请问如何把图片连续帧转成视频推流出去,完全不知道要怎么弄

sunkunGitHub commented 3 months ago

我用如下代码已实现推流,但是仍有几个问题 1、无法推送rtsp的流,提示Protocol not found 协议不存在 2、推出去的流使用vlc播放时播放读秒每次增加3-4秒,画面也不更新

private static void MakeMp4(Codec codec, int width, int height, int frameCount = 30)

    {

        using FormatContext infc = FormatContext.OpenInputUrl("rtsp://admin:1234@10.36.3.92");

        infc.LoadStreamInfo();

        MediaStream videoStream = infc.GetVideoStream();

        using CodecContext videoDecoder = new(Codec.FindDecoderById(videoStream.Codecpar!.CodecId));

        videoDecoder.FillParameters(videoStream.Codecpar!);

        videoDecoder.Open();

        using FormatContext fc = FormatContext.AllocOutput(formatName: "flv");

        fc.VideoCodec = codec;

        MediaStream vstream = fc.NewStream(fc.VideoCodec);

        using CodecContext vcodec = new CodecContext(fc.VideoCodec)

        {

            Width = width,

            Height = height,

            TimeBase = new AVRational(1, 1000),

            PixelFormat = AVPixelFormat.Yuv420p,

            Flags = AV_CODEC_FLAG.GlobalHeader,

        };

        vcodec.Open(fc.VideoCodec, new MediaDictionary

        {

            ["preset"] = "ultrafast"

        });

        vstream.Codecpar!.CopyFrom(vcodec);

        using IOContext io = IOContext.OpenWrite("rtmp://127.0.0.1:1935/live/1");

        fc.Pb = io;

        fc.WriteHeader();

        foreach (Packet packet in infc.ReadPackets(videoStream.Index))

        {

            try

            {

                packet.RescaleTimestamp(vcodec.TimeBase, vstream.TimeBase);

                packet.StreamIndex = vstream.Index;

                fc.InterleavedWritePacket(packet);

            }

            finally

            {

                packet.Unref();

            }

        }

        fc.WriteTrailer();
    }