You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET/MAUI中如何通过代码创建使用TextureView的ExoPlayer

在.NET MAUI中创建基于TextureView的ExoPlayer(纯C#实现)

问题说明

需要在.NET MAUI的Android平台上,用纯C#代码实现渲染到TextureView的ExoPlayer(StyledPlayerView),无需依赖XML文件。之前尝试通过XML片段创建IAttributeSet时遇到两个错误:

  • XML解析报错:System.Xml.XmlException: 'android' is an undeclared prefix
  • 类型转换异常:Java.Lang.ClassCastException: 'android.util.XmlPullAttributes cannot be cast to android.content.res.XmlBlock$Parser

解决方案1:直接设置SurfaceType(推荐)

无需构造AttributeSet,创建StyledPlayerView后直接调用SetSurfaceType方法指定使用TextureView,代码更简洁:

using Android.Content;
using Com.Google.Android.Exoplayer2;
using Com.Google.Android.Exoplayer2.UI;
using Com.Google.Android.Exoplayer2.Source.Progressive;
using Com.Google.Android.Exoplayer2.Upstream;

// 获取当前Context(示例:在MAUI自定义ViewHandler中可通过Context属性获取)
Context context = Android.App.Application.Context;

// 1. 创建StyledPlayerView实例
StyledPlayerView playerView = new StyledPlayerView(context);

// 2. 设置SurfaceType为TextureView
playerView.SetSurfaceType(PlayerView.SurfaceTypeTextureView);

// 3. 初始化ExoPlayer并关联到PlayerView
SimpleExoPlayer player = new SimpleExoPlayer.Builder(context).Build();
playerView.Player = player;

// 4. 设置播放源(示例:播放网络视频)
Uri videoUri = Uri.Parse("https://example.com/your-video.mp4");
DataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory();
ProgressiveMediaSource mediaSource = new ProgressiveMediaSource.Factory(dataSourceFactory)
    .CreateMediaSource(MediaItem.FromUri(videoUri));
player.Prepare(mediaSource);

// 5. 将PlayerView添加到布局(示例:在MAUI自定义Handler中赋值给PlatformView)
// this.PlatformView = playerView;

解决方案2:纯代码创建IAttributeSet(构造函数传参方式)

若必须通过构造函数的IAttributeSet参数指定SurfaceType,可通过Android原生Xml解析方式创建正确的AttributeSet,避免之前的错误:

using Android.Content;
using Android.Content.Res;
using Android.Runtime;
using Com.Google.Android.Exoplayer2.UI;
using Org.Xmlpull.V1;
using System.IO;

Context context = Android.App.Application.Context;

// 构造包含命名空间和surface_type属性的XML字符串
string xml = @"<?xml version=""1.0"" encoding=""utf-8""?>
<com.google.android.exoplayer2.ui.StyledPlayerView
    xmlns:app=""http://schemas.android.com/apk/res-auto""
    app:surface_type=""texture_view"" />";

// 使用Android原生XmlPullParser解析XML
XmlPullParser parser = Xml.NewPullParser();
parser.SetInput(new StringReader(xml), "utf-8");
parser.NextTag(); // 移动到根节点

// 创建AttributeSet(使用Android的XmlBlock.Parser,避免类型转换异常)
using (XmlBlock xmlBlock = new XmlBlock(context.AssetManager, xml, "utf-8"))
{
    using (XmlBlock.Parser xmlParser = xmlBlock.NewParser())
    {
        xmlParser.NextTag();
        IAttributeSet attrs = Xml.AsAttributeSet(xmlParser);
        
        // 通过构造函数创建StyledPlayerView
        StyledPlayerView playerView = new StyledPlayerView(context, attrs);
        
        // 后续初始化Player等操作同方案1
    }
}

代码说明

  1. 方案1利用PlayerView提供的SetSurfaceType方法直接切换渲染表面,无需处理XML和AttributeSet,是最简便的实现方式。
  2. 方案2解决了之前的错误:
    • XML字符串中声明了ExoPlayer的命名空间xmlns:app="http://schemas.android.com/apk/res-auto",避免前缀未声明的错误。
    • 使用Android原生的XmlBlock.Parser创建AttributeSet,而非XmlPullAttributes,解决了类型转换异常问题。

内容的提问来源于stack exchange,提问作者mike

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 12:53:15