最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

WPF實(shí)現(xiàn)播放RTSP視頻流

 更新時(shí)間:2025年01月24日 09:56:28   作者:xhubobo  
這篇文章主要為大家詳細(xì)介紹了WPF實(shí)現(xiàn)播放RTSP視頻流的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

在WPF中可以使用LibVLCSharp.WPF、Vlc.DotNet.Wpf組件直接播放RTSP流,此外還可以通過(guò)LibVLCSharp + SkiaSharp的方式將VLC視頻流通過(guò)WriteableBitmap的方式關(guān)聯(lián)到Image對(duì)象。

1、LibVLCSharp.WPF

使用VideoView控件可以方便地播放RTSP視頻流。該方法使用簡(jiǎn)單,但是不能很好的對(duì)RTSP流圖像進(jìn)行處理。

(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對(duì)象

_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對(duì)象

_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視頻流經(jīng)過(guò)處理后輕松綁定到Image對(duì)象。同時(shí),通過(guò)改造VlcVideoSourceProvider類可以實(shí)現(xiàn)自由設(shè)置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

通過(guò)設(shè)置MediaPlayer的視頻回調(diào)方法,在視頻VideoLock回調(diào)中將視頻圖像拷貝至緩存中,然后在VideoDisplay回調(diào)中將緩存中的數(shù)據(jù)轉(zhuǎn)換為SKImage繪制在Skia畫布中,之后刷新關(guān)聯(lián)的位圖即可。

(1) 引入NuGet包

LibVLCSharp、SkiaSharp。

(2) 初始化LibVLCSharp

LibVLCSharp.Shared.Core.Initialize();

(3) 初始化LibVLC對(duì)象

_libVlc = new LibVLC(true);
_mediaPlayer = new MediaPlayer(_libVlc)
{
    Volume = 0, //靜音
    EnableHardwareDecoding = true //硬件加速
};
_mediaPlayer.EndReached += OnPlayerEndReached;
_mediaPlayer.Stopped += OnPlayerStopped;

(4) Loaded事件中設(shè)置視頻回調(diào)

_mediaPlayer.SetVideoFormatCallbacks(OnLibVLCVideoFormat, null);
_mediaPlayer.SetVideoCallbacks(OnLibVLCVideoLock, null, OnLibVLCVideoDisplay);

(5) Unloaded事件中銷毀VLC對(duì)象

_mediaPlayer.Stop();
_mediaPlayer.Dispose();
_libVlc.Dispose();

(6) 視頻回調(diào)處理

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();
}

到此這篇關(guān)于WPF實(shí)現(xiàn)播放RTSP視頻流的文章就介紹到這了,更多相關(guān)WPF播放RTSP視頻流內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C#操作windows注冊(cè)表的方法

    C#操作windows注冊(cè)表的方法

    這篇文章主要介紹了C#操作windows注冊(cè)表的方法,涉及C#針對(duì)注冊(cè)表的讀取與寫入技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • C#制作多線程處理強(qiáng)化版網(wǎng)絡(luò)爬蟲(chóng)

    C#制作多線程處理強(qiáng)化版網(wǎng)絡(luò)爬蟲(chóng)

    這篇文章主要介紹了C#制作多線程處理強(qiáng)化版網(wǎng)絡(luò)爬蟲(chóng)的相關(guān)代碼,有想學(xué)習(xí)C#多線程編程的小伙伴可以參考下
    2016-09-09
  • C# new與malloc的使用與區(qū)別

    C# new與malloc的使用與區(qū)別

    本文主要介紹了C# new與malloc的使用與區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • C#基礎(chǔ)知識(shí)之Partial的使用

    C#基礎(chǔ)知識(shí)之Partial的使用

    這篇文章主要介紹了C#基礎(chǔ)知識(shí)之Partial的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 總結(jié)C#刪除字符串?dāng)?shù)組中空字符串的幾種方法

    總結(jié)C#刪除字符串?dāng)?shù)組中空字符串的幾種方法

    C#中要如何才能刪除一個(gè)字符串?dāng)?shù)組中的空字符串呢?下面的文章會(huì)介紹多種方式來(lái)實(shí)現(xiàn)清除數(shù)組中的空字符串,以及在.net中將字符串?dāng)?shù)組中字符串為空的元素去除。
    2016-08-08
  • C#程序中session的基本設(shè)置示例及清除session的方法

    C#程序中session的基本設(shè)置示例及清除session的方法

    這篇文章主要介紹了C#程序中session的基本設(shè)置示例及清除session的方法,是C#入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2016-04-04
  • c#中token的使用方法實(shí)例

    c#中token的使用方法實(shí)例

    本文主要介紹了c#中token的使用方法實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C#中常用的正則表達(dá)式實(shí)例

    C#中常用的正則表達(dá)式實(shí)例

    正則表達(dá)式在程序設(shè)計(jì)中有著重要的位置,它經(jīng)常被用于處理字符串信息,下面是C#中常用的正則表達(dá)式實(shí)例,感興趣的朋友一起看看吧
    2016-10-10
  • C#中的TemplateMethod模式問(wèn)題分析

    C#中的TemplateMethod模式問(wèn)題分析

    這篇文章主要介紹了C#中的TemplateMethod模式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • C#獲取指定文件著作權(quán)信息的方法

    C#獲取指定文件著作權(quán)信息的方法

    這篇文章主要介紹了C#獲取指定文件著作權(quán)信息的方法,涉及C#中FileVersionInfo類的使用技巧,需要的朋友可以參考下
    2015-04-04

最新評(píng)論

锦屏县| 岗巴县| 鹤庆县| 贡嘎县| 周口市| 弋阳县| 齐齐哈尔市| 剑河县| 合肥市| 天柱县| 万盛区| 东山县| 新巴尔虎左旗| 龙陵县| 鄱阳县| 裕民县| 和田市| 宁波市| 广昌县| 广宗县| 黎城县| 海伦市| 陆河县| 陕西省| 黔西| 循化| 改则县| 衢州市| 重庆市| 阳原县| 莎车县| 宁夏| 建水县| 延长县| 恩平市| 定日县| 通城县| 成都市| 晋州市| 运城市| 黄梅县|