来自图像的 Rtsp 流 C#

问题描述 投票:0回答:0

大家下午好。我正在尝试从 WPF 控件渲染的图像实现 rtsp 广播。我能够将图像保存在文件夹中,因此它们是正确的。我使用 VLC 进行流媒体播放。 我制作了自己的 Stream 实现,其中使用 BlockingCollection 来存储帧。调用 Read 方法时,我从集合中取出一帧并将其复制到缓冲区。 当我尝试通过 VLC 播放器连接到广播时,收到错误“此源未打开” 我真的不明白问题出在哪里。我希望得到你的帮助。 预先感谢)

主课

using LibVLCSharp.Shared;
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using MediaPlayer = LibVLCSharp.Shared.MediaPlayer;

namespace Presenter.Infrastructure.Services
{
    public class LANViewerService : IViewerService
    {
        private static LANViewerService instance;
        Task produceTask;
        private bool play;
        private MediaPlayer player;

        public Visual? PresentationField { get; set; }

        public event EventHandler PresentationEnded;
        public event EventHandler PresentationStarted;

        private LANViewerService() { }

        public static IViewerService GetViewerService() => instance ??= new LANViewerService();

        public void EndPresentation()
        {
            play = false;
            player.Stop();
            PresentationEnded?.Invoke(this, EventArgs.Empty);
        }

        public void StartPresentation()
        {
            Core.Initialize();
            var libvlc = new LibVLC();
            libvlc.Log += Libvlc_Log;
            player = new MediaPlayer(libvlc);
            player.Play();

            PresentationStarted?.Invoke(this, EventArgs.Empty);

            VideoStream videoStream = new VideoStream();
            var media = new Media(libvlc, new StreamMediaInput(videoStream));
            media.AddOption(":no-audio");
            media.AddOption(":sout=#transcode{vcodec=h264,fps=10,vb=1024,acodec=none}");
            media.AddOption(":sout=#rtp{sdp=rtsp://127.0.0.1:8008/test}");
            media.AddOption(":sout-keep");
            player.Media = media;
            player.Play();

            produceTask = new Task(() =>
            {
                while (play)
                {
                    if (PresentationField == null)
                        continue;
                    RenderTargetBitmap bitmap = null;
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        JpegBitmapEncoder encoder = new();
                        bitmap = ConvertToBitmapSource(PresentationField);
                        encoder.Frames.Add(BitmapFrame.Create(bitmap));
                        MemoryStream stream = new MemoryStream();
                        encoder.Save(stream);
                        videoStream.Write(stream.ToArray());
                    });

                    Thread.Sleep(30);
                }
            });
            play = true;
            produceTask.Start();
        }

        private void Libvlc_Log(object? sender, LogEventArgs e)
        {
            Debug.WriteLine(e.Module + " " + e.Message);
        }

        public RenderTargetBitmap ConvertToBitmapSource(Visual element)
        {
            var target = new RenderTargetBitmap(1920, 1080, 96, 96, PixelFormats.Default);
            target.Render(element);

            return target;
        }

直播课程

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;

namespace Presenter.Infrastructure
{
    public class VideoStream : Stream, IDisposable
    {
        BlockingCollection<byte[]> frames;
        IEnumerator<byte[]> enumerator;
        private bool _disposed;

        public override bool CanRead => true;

        public override bool CanSeek => false;
        public override bool CanWrite => true;

        public override long Length => int.MaxValue;

        public override long Position { get; set; } = 0;

        public VideoStream()
        {
            frames = new();
            enumerator = frames.GetConsumingEnumerable().GetEnumerator();
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            byte[] frame = frames.Take();
            int readed = frame.Length < count ? frame.Length : count;
            Array.Copy(frame, 0, buffer, offset, readed);  
            return readed;
        }

        public override int Read(Span<byte> buffer)
        {
            byte[] frame = frames.Take();
            frame.CopyTo(buffer);
            return frame.Length;
        }

        public void Write(byte[] frame)
        {
            frames.Add(frame);
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            throw new InvalidOperationException();
        }

        public override void SetLength(long value)
        {
            throw new InvalidOperationException();
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            
        }

        public override void Flush()
        {
            throw new InvalidOperationException();
        }

        void IDisposable.Dispose()
        {
            if (_disposed)
                return;

            enumerator.Dispose();
            _disposed = true;
        }
    }
}

调试日志

main creating audio output
mmdevice cannot initialize COM (error 0x80010106)
main looking for audio output module matching "any": 6 candidates
main revision 3.0.18-0-ge9eceaed4d
main configured with /builds/videolan/vlc/extras/package/win32/../../../configure  '--enable-update-check' '--enable-lua' '--enable-faad' '--enable-flac' '--enable-theora' '--enable-avcodec' '--enable-merge-ffmpeg' '--enable-dca' '--enable-mpc' '--enable-libass' '--enable-schroedinger' '--enable-realrtsp' '--enable-live555' '--enable-shout' '--enable-goom' '--enable-sse' '--enable-mmx' '--enable-libcddb' '--enable-zvbi' '--disable-telx' '--enable-nls' '--host=x86_64-w64-mingw32' '--with-contrib=../contrib/x86_64-w64-mingw32' '--with-breakpad=https://win.crashes.videolan.org' '--enable-qt' '--enable-skins2' '--enable-dvdread' '--enable-caca' 'host_alias=x86_64-w64-mingw32' 'CFLAGS= ' 'CXXFLAGS= ' 'PKG_CONFIG=pkg-config' 'PKG_CONFIG_LIBDIR=/usr/x86_64-w64-mingw32/lib/pkgconfig:/usr/lib/x86_64-w64-mingw32/pkgconfig'
main using audio output module "directsound"
directsound found 3 devices
main keeping audio output
main Copyright © 1996-2022 the VideoLAN team
main VLC media player - 3.0.18 Vetinari
main Creating an input for 'imem://'
main using sout chain=`rtp{sdp=rtsp://127.0.0.1:8008/test}'
main looking for sout stream module matching "rtp": 23 candidates
main set config option: sout-rtp-sdp to rtsp://127.0.0.1:8008/test
stream_out_rtp Consider passing --rtsp-host=IP on the command line instead.
main using timeshift granularity of 50 MiB
main `imem://' gives access `imem' demux `any' path `'
stream_out_rtp RTSP stream at /test
main net: listening to 127.0.0.1 port 8008
main no access_demux modules matched
main looking for access_demux module matching "imem": 15 candidates
prefetch using 16777216 bytes buffer, 16777216 bytes read
main using stream_filter module "prefetch"
main creating access: imem://
main using access module "imem_access"
main using timeshift path: C:\Users\Konstant\AppData\Local\Temp
main using sout stream module "stream_out_rtp"
main creating demux: access='imem' demux='any' location='' file='(null)'
main stream=`rtp'
stream_out_rtp "127.0.0.1" RTSP host might be ignored in multiple-host configurations, use at your own risks.
main looking for access module matching "imem": 27 candidates
imem Invalid get/release function pointers
main looking for stream_filter module matching "prefetch,cache_read": 24 candidates
main looking for stream_filter module matching "any": 24 candidates
304219
lua Trying Lua scripts in C:\Users\Konstant\AppData\Roaming\vlc\lua\playlist
lua Trying Lua scripts in C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\playlist
lua Trying Lua playlist script C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\playlist\anevia_streams.luac
lua Trying Lua playlist script C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\playlist\anevia_xml.luac
lua Trying Lua playlist script C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\playlist\appletrailers.luac
lua Trying Lua playlist script C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\playlist\bbc_co_uk.luac
lua Trying Lua playlist script C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\playlist\cue.luac
lua Trying Lua playlist script C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\playlist\dailymotion.luac
lua Trying Lua playlist script C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\playlist\jamendo.luac
lua Trying Lua playlist script C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\playlist\koreus.luac
lua Trying Lua playlist script C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\playlist\liveleak.luac
lua Trying Lua playlist script C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\playlist\newgrounds.luac
lua Trying Lua playlist script C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\playlist\rockbox_fm_presets.luac
lua Trying Lua playlist script C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\playlist\soundcloud.luac
lua Trying Lua playlist script C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\playlist\twitch.luac
lua Trying Lua playlist script C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\playlist\vimeo.luac
lua Trying Lua playlist script C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\playlist\vocaroo.luac
lua Trying Lua playlist script C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\playlist\youtube.luac
main no stream_filter modules matched
main creating demux: access='imem' demux='any' location='' file='(null)'
main looking for demux module matching "any": 55 candidates
main using xml reader module "xml"
main using packetizer module "copy"
main using demux module "image"
main looking for meta reader module matching "any": 2 candidates
lua Trying Lua scripts in C:\Users\Konstant\AppData\Roaming\vlc\lua\meta\reader
lua Trying Lua scripts in C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\meta\reader
lua Trying Lua playlist script C:\Users\Konstant\Documents\Projects\Presenter\Presenter\bin\Debug\net6.0-windows\libvlc\win-x64\lua\meta\reader\filename.luac
main no meta reader modules matched
main `imem://' successfully opened
main EOF reached
main killing decoder fourcc `jpeg'
main removing module "copy"
main removing module "image"
main removing module "record"
main removing module "prefetch"
main starting in async mode
main selecting program id=0
main looking for packetizer module matching "any": 25 candidates
webvtt subtitle demux discarded
image Failed to load the image
image image too large (2147483647 > 134217728), rejected
image Detected image: JPEG
main using stream_filter module "record"
main no stream_directory modules matched
main looking for xml reader module matching "any": 1 candidates
main looking for stream_directory module matching "any": 1 candidates
main looking for stream_filter module matching "record": 24 candidates
main attachment of directory-extractor failed for imem://
304219
prefetch end of stream
The thread 0x2180 has exited with code 0 (0x0).
main removing module "imem_access"
main Program doesn't contain anymore ES

附注我提前为我的英语感到抱歉。

c# wpf vlc libvlcsharp
© www.soinside.com 2019 - 2024. All rights reserved.