当前位置: 代码网 > it编程>编程语言>C# > WPF实现播放RTSP视频流

WPF实现播放RTSP视频流

2025年02月13日 C# 我要评论
在wpf中可以使用libvlcsharp.wpf、vlc.dotnet.wpf组件直接播放rtsp流,此外还可以通过libvlcsharp + skiasharp的方式将vlc视频流通过writeab

在wpf中可以使用libvlcsharp.wpf、vlc.dotnet.wpf组件直接播放rtsp流,此外还可以通过libvlcsharp + skiasharp的方式将vlc视频流通过writeablebitmap的方式关联到image对象。

1、libvlcsharp.wpf

使用videoview控件可以方便地播放rtsp视频流。该方法使用简单,但是不能很好的对rtsp流图像进行处理。

(1) 引入nuget包

libvlcsharp.wpf。

(2) 初始化libvlcsharp

libvlcsharp.shared.core.initialize();

(3) 使用videoview控件

<grid horizontalalignment="stretch" verticalalignment="stretch">
    <wpf:videoview x:name="videoview"/>
</grid>

(4) 初始化libvlc对象

_libvlc = new libvlc(true);
_mediaplayer = new mediaplayer(_libvlc)
{
    volume = 0, //静音
    enablehardwaredecoding = true //硬件加速
};
_mediaplayer.endreached += onplayerendreached;
_mediaplayer.stopped += onplayerstopped;

videoview.ismanipulationenabled = true;
videoview.isenabled = true;
videoview.loaded += (sender, args) =>
{
    videoview.mediaplayer = _mediaplayer;
};

(5) unloaded事件中销毁vlc对象

_mediaplayer.stop();
_mediaplayer.dispose();
_libvlc.dispose();

(6) 播放rtsp

var options = new[]
{
    "file-caching=300",
    "live-capture-caching=300",
    "disc-caching-caching=300",
    "network-caching=333",
    "live-caching=300"
};
using (var media = new media(_libvlc, new uri(camerapara.url), options))
{
    videoview.mediaplayer.play(media);
}

(7) 停止播放

if (videoview.mediaplayer.isplaying)
{
    videoview.mediaplayer.stop();
}

2、vlc.dotnet.wpf

借助于vlcvideosourceprovider类,可以将rtsp视频流经过处理后轻松绑定到image对象。同时,通过改造vlcvideosourceprovider类可以实现自由设置rtsp视频流的播放帧率(fps)。

(1) 引入nuget包

vlc.dotnet.wpf。

(2) 启用位图缓存

<usercontrol.cachemode>
    <bitmapcache/>
</usercontrol.cachemode>

(3)  初始化sourceprovider

_sourceprovider = new vlcvideosourceprovider(dispatcher);

_sourceprovider.createplayer(_libdirectory, "--no-audio", "--rtsp-tcp");
_sourceprovider.mediaplayer.stopped += onplayerstopped;

videoimage.setbinding(image.sourceproperty,
    new binding(nameof(vlcvideosourceprovider.videosource))
    {
        source = _sourceprovider
    });

(4) 播放rtsp视频流

var options = new[]
{
    "file-caching=300",
    "live-capture-caching=300",
    "disc-caching-caching=300",
    "network-caching=333",
    "live-caching=300",
    harddecoding ? "avcodec-hw=any" : "" //硬解码
};
_sourceprovider.mediaplayer.play(new uri(camerapara.url), options);

(5) 停止播放

if (_sourceprovider.mediaplayer.isplaying())
{
    _sourceprovider?.mediaplayer?.dispose();
    _sourceprovider?.dispose();
    _sourceprovider = null;
}

3、libvlcsharp + skiasharp

通过设置mediaplayer的视频回调方法,在视频videolock回调中将视频图像拷贝至缓存中,然后在videodisplay回调中将缓存中的数据转换为skimage绘制在skia画布中,之后刷新关联的位图即可。

(1) 引入nuget包

libvlcsharp、skiasharp。

(2) 初始化libvlcsharp

libvlcsharp.shared.core.initialize();

(3) 初始化libvlc对象

_libvlc = new libvlc(true);
_mediaplayer = new mediaplayer(_libvlc)
{
    volume = 0, //静音
    enablehardwaredecoding = true //硬件加速
};
_mediaplayer.endreached += onplayerendreached;
_mediaplayer.stopped += onplayerstopped;

(4) loaded事件中设置视频回调

_mediaplayer.setvideoformatcallbacks(onlibvlcvideoformat, null);
_mediaplayer.setvideocallbacks(onlibvlcvideolock, null, onlibvlcvideodisplay);

(5) unloaded事件中销毁vlc对象

_mediaplayer.stop();
_mediaplayer.dispose();
_libvlc.dispose();

(6) 视频回调处理

private uint onlibvlcvideoformat(ref intptr opaque, intptr chroma,
        ref uint width, ref uint height, ref uint pitches, ref uint lines)
    // resharper restore redundantassignment
{
    var bytes = encoding.ascii.getbytes("rv32"); //i420, rv32, avc1
    for (var i = 0; i < bytes.length; i++)
    {
        marshal.writebyte(chroma, i, bytes[i]);
    }

    if (_mediaplayer.media is media media)
    {
        foreach (mediatrack track in media.tracks)
        {
            if (track.tracktype == tracktype.video)
            {
                var trackinfo = track.data.video;
                if (trackinfo.width > 0 && trackinfo.height > 0)
                {
                    width = trackinfo.width;
                    height = trackinfo.height;
                }

                break;
            }
        }
    }

    var pixelformat = pixelformats.bgra32;
    pitches = (uint) (width * pixelformat.bitsperpixel) / 8;
    lines = height;

    _videowidth = (int) width;
    _videoheight = (int) height;

    _buffer = new byte[_videowidth * _videoheight * 4];
    _plane = marshal.unsafeaddrofpinnedarrayelement(_buffer, 0);

    dispatcher.invoke(delegate
    {
        _bitmap = new writeablebitmap(_videowidth, _videoheight, 96, 96, pixelformats.bgra32, null);
        _imageinfo = new skimageinfo(_videowidth, _videoheight, skcolortype.bgra8888);
        _surface = sksurface.create(
            new skimageinfo(_videowidth, _videoheight, skimageinfo.platformcolortype, skalphatype.premul),
            _bitmap.backbuffer, _bitmap.backbufferstride);
        _rect = new int32rect(0, 0, _videowidth, _videoheight);

        videoimage.source = _bitmap;
        videoimage.stretch = ismaincontrol ? stretch.fill : stretch.uniform;
    });

    return 1;
}

private intptr onlibvlcvideolock(intptr opaque, intptr planes)
{
    intptr[] dataarray = {_plane};
    marshal.copy(dataarray, 0, planes, dataarray.length);
    return intptr.zero;
}

private void onlibvlcvideodisplay(intptr opaque, intptr picture)
{
    var image = skimage.frompixels(_imageinfo, _plane);
    _surface.canvas.drawimage(image, new skpoint(0, 0));

    dispatcher.invoke(delegate
    {
        _bitmap.lock();
        _bitmap.adddirtyrect(_rect);
        _bitmap.unlock();
    });
}

(7) 播放rtsp视频

var options = new[]
{
    "file-caching=300",
    "live-capture-caching=300",
    "disc-caching-caching=300",
    "network-caching=333",
    "live-caching=300"
};
using (var media = new media(_libvlc, new uri(camerapara.url), options))
{
    _mediaplayer.play(media);
}

(8) 停止播放

if (_mediaplayer.isplaying)
{
    _mediaplayer.stop();
}

到此这篇关于wpf实现播放rtsp视频流的文章就介绍到这了,更多相关wpf播放rtsp视频流内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com