WPF下播放Rtmp的解决方案
介绍
在实际的开发过程中,需要在应用内部内嵌播放器进行视频的播放。官方默认的MediaElement控件只能播放有限的视频格式,也不能播放网络流。比较流行的解决方式是vlc的库,但是在实际使用过程中发现有很多问题。这里给大家推荐另一个比较好的库。
使用
官网地址
安装库
Nuget下安装FFME.Windows
PM> Install-Package FFME.Windows
下载ffmpeg依赖
注:官网给的地址我在实际使用中发现,使用官方的代码没问题,使用给定的步骤使用就会抱错,如果你们跟我一样给大家推荐另一个ffmpeg包的地址
ffmpeg依赖下载地址
代码
- 指定ffmpeg库的地址
Unosquare.FFME.Library.FFmpegDirectory = @"C:\ffmpeg\ffmpeg-4.4-windows-desktop-vs2022-gpl-lite\bin";
- xaml中插入控件
<Window x:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WpfApp1" xmlns:ffme="clr-namespace:Unosquare.FFME;assembly=ffme.win"mc:Ignorable="d"Loaded="Window_Loaded"Closed="Window_Closed"Title="MainWindow" Height="300" Width="600"><Grid><ffme:MediaElement x:Name="Media" Background="Gray" LoadedBehavior="Play" UnloadedBehavior="Manual" /><Button Content="Play" Click="PlayButton_Click" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="10"/><Button Content="Stop" Click="StopButton_Click" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="100,10,0,0"/></Grid>
</Window>
- 监听失败的事件
Media.MediaFailed += OnMediaFailed;
- 创建一个处理流地址的类
FileInputStream
namespace Unosquare.FFME.Windows.Sample.Foundation;using Common;
using FFmpeg.AutoGen;
using System;
using System.IO;
using System.Runtime.InteropServices;/// <inheritdoc />
/// <summary>
/// Provides an example of a very simple custom input stream.
/// </summary>
/// <seealso cref="IMediaInputStream" />
public sealed unsafe class FileInputStream : IMediaInputStream
{private readonly FileStream BackingStream;private readonly object ReadLock = new();private readonly byte[] ReadBuffer;/// <summary>/// Initializes a new instance of the <see cref="FileInputStream"/> class./// </summary>/// <param name="path">The path.</param>public FileInputStream(string path){var fullPath = Path.GetFullPath(path);BackingStream = File.OpenRead(fullPath);var uri = new Uri(fullPath);StreamUri = new Uri(uri.ToString().ReplaceOrdinal("file://", Scheme));CanSeek = true;ReadBuffer = new byte[ReadBufferLength];}/// <summary>/// The custom file scheme (URL prefix) including the :// sequence./// </summary>public static string Scheme => "customfile://";/// <inheritdoc />public Uri StreamUri { get; }/// <inheritdoc />public bool CanSeek { get; }/// <inheritdoc />public int ReadBufferLength => 1024 * 16;/// <inheritdoc />public InputStreamInitializing OnInitializing { get; }/// <inheritdoc />public InputStreamInitialized OnInitialized { get; }/// <inheritdoc />public void Dispose(){BackingStream?.Dispose();}/// <summary>/// Reads from the underlying stream and writes up to <paramref name="targetBufferLength" /> bytes/// to the <paramref name="targetBuffer" />. Returns the number of bytes that were written./// </summary>/// <param name="opaque">The opaque.</param>/// <param name="targetBuffer">The target buffer.</param>/// <param name="targetBufferLength">Length of the target buffer.</param>/// <returns>/// The number of bytes that have been read./// </returns>public int Read(void* opaque, byte* targetBuffer, int targetBufferLength){lock (ReadLock){try{var readCount = BackingStream.Read(ReadBuffer, 0, ReadBuffer.Length);if (readCount > 0)Marshal.Copy(ReadBuffer, 0, (IntPtr)targetBuffer, readCount);else if (readCount == 0)return ffmpeg.AVERROR_EOF;return readCount;}catch (Exception){return ffmpeg.AVERROR_EOF;}}}/// <inheritdoc />public long Seek(void* opaque, long offset, int whence){lock (ReadLock){try{return whence == ffmpeg.AVSEEK_SIZE ?BackingStream.Length : BackingStream.Seek(offset, SeekOrigin.Begin);}catch{return ffmpeg.AVERROR_EOF;}}}
}
- 播放视频
//var target = new Uri(@"rtmp://127.0.0.1/live/test1231233");
var target = new Uri(@"D:\视频\泥坑.mp4");
if (target.ToString().StartsWith(FileInputStream.Scheme, StringComparison.OrdinalIgnoreCase))await Media.Open(new FileInputStream(target.LocalPath));
elseawait Media.Open(target);
相关文章:
WPF下播放Rtmp的解决方案
介绍 在实际的开发过程中,需要在应用内部内嵌播放器进行视频的播放。官方默认的MediaElement控件只能播放有限的视频格式,也不能播放网络流。比较流行的解决方式是vlc的库,但是在实际使用过程中发现有很多问题。这里给大家推荐另一个比较好的…...
7.高可用集群架构Keepalived双主热备原理
一. 高可用集群架构Keepalived双主热备原理 (1)主机+备机keepalived配置(192.168.1.171) ! Configuration File for keepalivedglobal_defs {# 路由id:当前安装keepalived节点主机的标识符,全局唯一router_id keep_101 } #计算机节点(主机配置) vrrp_instance VI_1 {</...
为以人工智能为中心的工作负载重新设计的全局控制台
MinIO 控制台多年来一直是一个不断发展的产品。每次学习时,我们都会思考如何改进交互框架中这个非常重要的部分。首先是控制台,它在推出后的一年内就被广泛采用。更具体地说,超过 10K 个组织。接下来是企业控制台。这从对象存储与其 GUI 之间…...
go channel中的 close注意事项 range取数据
在使用 Go 语言中的 close 函数时,有一些注意事项需要牢记,以确保程序的健壮性和正确性: 1. **仅用于通道(channel)**: - close 函数只能用于关闭通道,不能用于关闭文件、网络连接或其他资源…...
Vue3 -- 项目配置之eslint【企业级项目配置保姆级教程1】
下面是项目级完整配置1➡eslint:【吐血分享,博主踩过的坑你跳过去!!跳不过去?太过分了给博主打钱】 浏览器自动打开项目: 你想释放双手吗?你想每天早上打开电脑运行完项目自动在浏览器打开吗&a…...
鸿蒙开发应用权限管理
简介 一种允许应用访问系统资源(如:通讯录等)和系统能力(如:访问摄像头、麦克风等)的通用权限访问方式,来保护系统数据(包括用户个人数据)或功能,避免它们被…...
【数据库】如何保证数据库迁移过程中数据的一致性?
在数据库迁移过程中,保证数据的一致性是非常重要的,尤其是在涉及到多个表、多个数据库或分布式系统的情况下。以下是一些确保数据一致性的最佳实践和方法: 1. 备份数据 在开始迁移之前,进行全面的数据备份是确保数据一致性的第…...
C++之内存管理
🌹个人主页🌹:喜欢草莓熊的bear 🌹专栏🌹:C入门 目录 前言 一、C/C内存分配 二、 malloc、calloc、realloc、free 三、C内存管理方式 3.1 new/delete 操作内置类型 3.2 new和detele操作自定义类型…...
ISP是什么?
isp全称为Internet Service Provider,即互联网服务提供商,是一种向用户提供互联网接入服务的公司或组织,它们提供的服务包括互联网接入、域名注册、网站托管等等。 ISP的应用场景非常广泛,几乎所有的互联网用户都需要通过ISP来接…...
机房动环境监控用各种列表已经淘汰了,现在都是可视化图表展示了
在信息技术飞速发展的今天,机房作为数据存储、处理和传输的核心场所,其稳定运行至关重要。过去,机房动环境监控主要依赖各种列表形式来呈现数据,但如今,这种方式已经逐渐被淘汰,取而代之的是更加直观、高效…...
RHCE的练习(12)
写一个脚本,完成以下要求: 给定一个用户: 如果其UID为0,就显示此为管理员;否则,就显示其为普通用户; #!/bin/bash # 使用read命令获取用户名 read -p "请输入用户名: " username …...
uniapp自动注册机制:easycom
传统 Vue 项目中,我们需要注册、导入组件之后才能使用组件。 uniapp 框架提供了一种组件自动注册机制,只要你在 components 文件夹下新建的组件满足 /components/组件名/组件名.vue 的命名规范,就能直接使用。 注意:组件的文件夹…...
【论文阅读】(Security) Assertions by Large Language Models
论文笔记:(Security) Assertions by Large Language Models 来源:IEEE TRANSACTIONS ON INFORMATION FORENSICS AND SECURITY I. 引言 计算机系统的安全性通常依赖于硬件的根信任。硬件漏洞可能对系统造成严重影响,因此需要支持安全验证的技术。断言验证是一种流行的验证…...
C++ 编程基础(5)类与对象 | 5.8、面向对象五大原则
文章目录 一、面向对象五大原则1、单一功能(Single Responsibility Principle, SRP)2、开放封闭原则(Open/Closed Principle, OCP)3、里氏替换原则(Liskov Substitution Principle, LSP)4、接口隔离原则&am…...
node.js中express的基本了解
定义 Express是基于Node.js平台,快速、开放、极简的Web开发框架。 本质 Express是一个npm上的第三方包,提供了快速创建Web服务器的便捷方法。 作用 与Node.js内置的http模块类似,Express也是专门用来创建Web服务器的,但它极大地简…...
AI大模型(一):Prompt AI编程
一、Prompt Engineering,提示工程 提示工程也叫指令工程: Prompt是发给大模型的指令,比如【讲个睡前故事】、【用Python写个消消乐游戏】等;本质上大模型相关的工程工作,都是围绕prompt展开的;提示工程门…...
ArcGIS Pro属性表乱码与字段名3个汉字解决方案大总结
01 背景 我们之前在使用ArcGIS出现导出Excel中文乱码及shp添加字段3个字被截断的情况,我们有以下应对策略: 推荐阅读:ArcGIS导出Excel中文乱码及shp添加字段3个字被截断? 那如果我们使用ArGIS Pro出现上述问题,该如何…...
小程序-基于java+SpringBoot+Vue的驾校预约平台设计与实现
项目运行 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.硬件环境:…...
计算机网络网关简介
网关,在计算机网络中扮演着至关重要的角色,它如同不同语言间的翻译官,让不同网络协议、不同体系结构的网络能够相互通信。简而言之,网关就是一个网络连接到另一个网络的“关口”,负责数据的接收、转换与发送。 在局域…...
如何用python将pdf转换为json格式
使用 Python 将 PDF 文件转换为 JSON 格式,主要步骤如下: 读取 PDF 内容:首先使用一个库读取 PDF 文件内容,如 PyMuPDF 或 pdfplumber。这些库可以逐页提取文本,并返回结构化的数据。 组织数据到 JSON:将提…...
Conforme配置管理范式:类型安全与约定优先的实践指南
1. 项目概述:Conforme,一个被低估的配置管理范式在软件开发和系统运维的日常里,我们总在和“配置”打交道。数据库连接字符串、API密钥、功能开关、环境变量……这些看似零散的信息,却像乐谱上的音符,共同决定了应用如…...
2026AI急救点合规生死线:GDPR+《人工智能医疗应用管理办法》双轨审计 checklist(仅限首批参会者获取)
更多请点击: https://intelliparadigm.com 第一章:2026AI急救点合规性定义与时代紧迫性 2026AI急救点(AI Emergency Point, AIEP)并非传统意义上的物理站点,而是由国家AI治理框架强制要求部署的、具备实时风险拦截、模…...
系统设计:一致性哈希
原文:towardsdatascience.com/system-design-consistent-hashing-43ddf48d2d32 https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/25fd590876caa1d6c711fa521ea11f98.png 简介 我们生活在一个每天都会大量生成数据的世界上。在…...
ThinkPad风扇控制终极指南:TPFanCtrl2让你的笔记本更安静高效 [特殊字符]
ThinkPad风扇控制终极指南:TPFanCtrl2让你的笔记本更安静高效 🚀 【免费下载链接】TPFanCtrl2 ThinkPad Fan Control 2 (Dual Fan) for Windows 10 and 11 项目地址: https://gitcode.com/gh_mirrors/tp/TPFanCtrl2 作为ThinkPad用户,…...
KMS智能激活工具终极指南:一键解决Windows和Office激活难题
KMS智能激活工具终极指南:一键解决Windows和Office激活难题 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO KMS_VL_ALL_AIO是一款强大的智能激活脚本,能够帮助用户轻松解…...
【2026 AI大会签到终极指南】:3大预检漏洞、5步零失败通关、24小时倒计时避坑清单
更多请点击: https://intelliparadigm.com 第一章:2026年AI技术大会签到流程全景概览 2026年AI技术大会全面启用无感化、多模态融合签到系统,覆盖人脸识别、NFC工牌扫描、二维码核验及离线应急通道四大核心路径。所有参会者需提前72小时完成…...
FreeRDP-WebConnect实战:在Windows上为老旧系统(如Server 2008)搭建一个轻量级Web管理门户
FreeRDP-WebConnect实战:为老旧Windows系统构建安全Web管理门户 老旧Windows服务器在企业中仍承担着关键业务角色,但直接暴露RDP端口的安全隐患与繁琐的VPN管理让运维团队头疼不已。本文将手把手教你如何通过FreeRDP-WebConnect构建一个既安全又便捷的We…...
如何永久保存微信聊天记录?WeChatMsg完整指南让你轻松掌握
如何永久保存微信聊天记录?WeChatMsg完整指南让你轻松掌握 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/W…...
全面战争模组开发者的终极工具箱:RPFM如何重新定义游戏数据管理
全面战争模组开发者的终极工具箱:RPFM如何重新定义游戏数据管理 【免费下载链接】rpfm Rusted PackFile Manager (RPFM) is a... reimplementation in Rust and Qt6 of PackFile Manager (PFM), one of the best modding tools for Total War Games. 项目地址: ht…...
通过环境变量为Hermes Agent配置Taotoken自定义提供方
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 通过环境变量为Hermes Agent配置Taotoken自定义提供方 对于使用Hermes Agent框架的开发者而言,接入不同的模型服务商通…...
