Flutter使用Android原生播放器详解

接上篇:播放器-IOS(Swift)篇

安卓端原生播放器的接入思路与ios基本一致,所以本篇就不废话了,直接上代码:

创建插件VideoViewPlugin实现FlutterPlugin:

package io.flutter.plugins.videoplayer;
import android.util.Log;
import androidx.annotation.NonNull;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
public class VideoViewPlugin implements FlutterPlugin, ActivityAware {
    private final static String TAG = "VideoViewPlugin";
    FlutterPluginBinding fpBinding;
    @Override
    public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
        fpBinding = binding;
        Log.e(TAG, "onAttachedToEngine");
    }
    @Override
    public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
        Log.e(TAG, "onDetachedFromEngine");
    }
    @Override
    public void onAttachedToActivity(@NonNull ActivityPluginBinding apBinding) {
        fpBinding.getPlatformViewRegistry().registerViewFactory("plugins.my_video_player/view", new VideoViewFactory(fpBinding, apBinding));
        Log.e(TAG, "onAttachedToActivity");
    }
    @Override
    public void onDetachedFromActivityForConfigChanges() {
        Log.e(TAG, "onDetachedFromActivityForConfigChanges");
    }
    @Override
    public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
        Log.e(TAG, "onReattachedToActivityForConfigChanges");
    }
    @Override
    public void onDetachedFromActivity() {
        Log.e(TAG, "onDetachedFromActivity");
    }
}

由于引用视频播放器时需要用到Activity的context,所以实现了ActivityAware接口,在onAttachedToActivity方法中注册PlatformViewFactory!

创建VideoViewFactory实现PlatformViewFactory:

package io.flutter.plugins.videoplayer;
import android.content.Context;
import io.flutter.Log;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.StandardMessageCodec;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugin.platform.PlatformViewFactory;
public class VideoViewFactory extends PlatformViewFactory {
    private final static String TAG = "VideoViewFactory";
    private final FlutterPlugin.FlutterPluginBinding fpBinding;
    private final ActivityPluginBinding apBinding;
    public VideoViewFactory(FlutterPlugin.FlutterPluginBinding fpBinding, ActivityPluginBinding apBinding) {
        super(StandardMessageCodec.INSTANCE);
        Log.e(TAG, "VideoViewFactory");
        this.fpBinding = fpBinding;
        this.apBinding = apBinding;
    }
    @Override
    public PlatformView create(Context context, int viewId, Object args) {
        Log.e(TAG, "PlatformView-create:" + args.toString());
        return new VideoViewPlayer(args.toString(), fpBinding, apBinding);
    }
}

创建VideoViewPlayer,实现PlatformView和MethodChannel.MethodCallHandler:

package io.flutter.plugins.videoplayer;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.th.kjjl_flutter.R;
import com.videoplayer.player.VideoView;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.platform.PlatformView;
public class VideoViewPlayer implements PlatformView, MethodChannel.MethodCallHandler {
    private final static String TAG = "VideoPlayerView";
    Activity context;
    private VideoView videoView;
    private MethodChannel methodChannel;
    VideoViewPlayer(String viewId, FlutterPlugin.FlutterPluginBinding fpBinding, ActivityPluginBinding apBinding) {
        this.context = apBinding.getActivity();
        videoView = (VideoView) LayoutInflater.from(context).inflate(R.layout.video_player, null);
        methodChannel = new MethodChannel(fpBinding.getBinaryMessenger(), "my_video_player_" + viewId);
        methodChannel.setMethodCallHandler(this);
    }
    @Override
    public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
        Log.e(TAG, "call.method>>" + call.method);
        switch (call.method) {
            case "setUrl":
                String url = call.arguments.toString();
                videoView.initVideoController(context);
                videoView.setUrl(url);
                break;
            case "start":
                videoView.start();
                break;
            case "pause":
                videoView.pause();
                break;
            case "release":
                videoView.pause();
                videoView.release();
                break;
            case "stopFullScreen":
                videoView.stopFullScreen();
                break;
            default:
                result.notImplemented();
        }
    }
    @Nullable
    @Override
    public View getView() {
        return videoView;
    }
    @Override
    public void dispose() {
        Log.e(TAG, "dispose>>");
        videoView.pause();
        videoView.release();
        methodChannel.setMethodCallHandler(null);
        methodChannel = null;
    }
}

其中的VideoView即引用的第三方播放器库,你可以根据自己情况,使用常见的安卓端开源播放器如GSY,饺子,DKPlayer等!

video_player.xml:

<?xml version="1.0" encoding="utf-8"?>
<com.videoplayer.player.VideoView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/videoView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

在MainActivity中注册插件:

class MainActivity : FlutterActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        flutterEngine!!.plugins.add(VideoViewPlugin())
    }
}

注意:不要在GeneratedPluginRegistrant中去注册插件包括IOS,这个类由系统自动生成其它第三方插件注册代码!安卓端在MainActivity中注册,IOS端在AppDelegate中注册!

flutter中的引用以及通信方法,上一篇已经写了,本篇就不再重复了!需要注意的是,插件名,插件id,methodChannel等,安卓,IOS和Flutter三端一定要一致!

到此这篇关于Flutter使用Android原生播放器详解的文章就介绍到这了,更多相关Flutter播放器内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 使用Flutter定位包获取地理位置

    目录 Flutter 中获取地理位置 先决条件 使用 Flutter 定位包 设置 位置权限 获取当前位置 使用 Flutter 地理编码包 设置 获取地址 常见的陷阱 结论 Flutter 中获取地理位置 如今,发现用户位置是移动应用程序非常常见且功能强大的用例.如果您曾经尝试过在 Android 中实现位置,您就会知道样例代码会变得多么复杂和混乱. 但这与 Flutter 不同--它有很多令人惊叹的包,可以为您抽象出样板代码,并使实现地理定位成为梦想.另一个好的方面是您可以在 Android

  • Flutter Component动画的显和隐最佳实践

    目录 动画选择决策树 Implicit Animations——隐式动画 基本使用 使用场景 TweenAnimationBuilder Explicit Animations——显示动画 基本使用 AnimatedWidget AnimatedBuilder 动画选择决策树 Flutter中包含大量的动画组件和自定义动画方式,所以,在合适的场景下选择合适的动画实现方式就成了决定代码质量好坏的一个重要因素. Flutter中的动画从广义上来讲可以分为两类,一类是基于绘制的动画(Drawing-b

  • Flutter高级玩法Flow位置自定义

    目录 前言 第一幕.开场-演员入台 1. 展示舞台 2. Flow出场 3. FlowDelegate出场 4. paintChildren方法和FlowPaintingContext对象 第二幕.排兵布阵 1. paintChild与Matrix4 2. Flow布局的封装 3. 圆形的Flow布局 第三幕.当Flow遇到Animation 1.圆形布局 + 旋转 2.圆形布局 + 偏移 前言 Flow布局是一个超级强大的布局,但应该很少有人用,因为入手的门槛还是有的 Flow的属性很简单,只

  • flutter 微信聊天输入框功能实现

    目录 chat_bottom.dart chat_element_other.dart chat_element_self.dart chat_input_box.dart page_chat_person.dart provider_chat_content.dart 高仿微信聊天输入框,效果图如下(目前都是静态展示,服务还没开始开发): 大家如果观察仔细的话 应该会发现,他输入框下面的高度 刚好就是 软键盘的高度:所以在这里就需要监听软键盘的高度.还要配置 resizeToAvoidBott

  • Flutter 自定义Drawer 滑出位置的大小实例代码详解

    Flutter开发过程中,Drawer控件的使用频率也是比较高的,其实有过移动端开发经验的人来说,Flutter中的Drawer控件就相当于ios开发或者Android开发中的"抽屉"效果,从侧边栏滑出导航菜单.对于Flutter中的Drawer控件的常规用法就不多介绍,网上大把的教程. 那么本篇博文分享一个网上教程不多的一个知识点,那就是自定义Drawer的滑出位置的大小,自定义Drawer滑出位置就需要修改一个double的widthPercent属性,widthPercent一般

  • Flutter学习之Navigator的高级用法分享

    目录 简介 named routes 给named route传参数 从Screen返回值 向Screen传值 总结 简介 上篇文章我们讲到了flutter中navigator的基本用法,我们可以使用它的push和pop方法来进行Router之间的跳转. 在flutter中一个Router就是一个widget,但是在Android中,一个Router就是Activity,在IOS中,一个Router是一个ViewController. Router除了之前讲过的push和pop方法之外,还有一些

  • Flutter使用Android原生播放器详解

    接上篇:播放器-IOS(Swift)篇 安卓端原生播放器的接入思路与ios基本一致,所以本篇就不废话了,直接上代码: 创建插件VideoViewPlugin实现FlutterPlugin: package io.flutter.plugins.videoplayer; import android.util.Log; import androidx.annotation.NonNull; import io.flutter.embedding.engine.plugins.FlutterPlug

  • Python实现多功能音乐播放器详解

    目录 前言 准备工作 知识点和所需模块 环境 完整代码 效果展示 导入模块 界面 按钮 功能 创建一个文件目录 音乐读取功能 显示已加载的音乐 播放音乐 停止播放 下一首 上一首 音量控制 关闭窗口 前言 就是用Python做一个简易的音乐播放器,废话不多说,咱们直接开干 当然,今天做这个肯定不是最简单的,最简单的音乐播放器,9行代码足以 import time import pygame file = r'歌曲路径' pygame.mixer.init() print('正在播放',file)

  • Android Flutter表格组件Table的使用详解

    目录 Table.TabRow.TabCell 小结 之前开发中用到的表格,本篇文章主要介绍如何在页面中使用表格做一个记录. Table组件不同于其它Flex布局,它是直接继承的RenderObjectWidget的.相当于是一个独立的组件,区别与其他系列组件. Table.TabRow.TabCell 惯例,先看下Table相关的构造方法: Table({ Key? key, this.children = const <TableRow>[],//行列表 表示多少行 this.column

  • Android Flutter实现精灵图的使用详解

    目录 前言 如何使用精灵图 自定义实现加载 Flame加载精灵图 前言 在日常开发中遇到的图片展示一般是静态图和Gif图两种形式(静态和动态的不同).与此同时当需要对图片做效果时让其动起来,常用方案是Gif图播放或者是帧动画(多种静态图轮询播放).但在游戏开发中还有一种动图表现形式叫做Sprite图(雪碧图),其在前端开发中也是很常见.为什么需要使用精灵图,因为每张图片显示都需要去发起请求获取,若页面图片数量较多(一个页面有几十个小图)并发请求将是一个大数量级,可能会造成页面加载速度降低,精灵图

  • Android 网络html源码查看器详解及实例

    Android 网络html源码查看器详解及实例 IO字节流的数据传输了解 Handler的基本使用 1.作品展示 2.需要掌握的知识 FileInputStream,FIleOutputStream,BufferInputStream,BufferOutStream的读写使用与区别 //进行流的读写 byte[] buffer = new byte[1024 * 8]; //创建一个写到内存的字节数组输出流 ByteArrayOutputStream byteArrayOutputStream

  • Android 控制车载蓝牙播放音乐详解流程

    需求:手机端音乐暂停和播放状态从服务端告诉客户端.设备端实现暂停.播放.上一首.下一首等功能 代码路径: packages/apps/Bluetooth/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java packages/apps/Bluetooth/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java pack

  • Android Flutter实现3D动画效果示例详解

    目录 前言 AnimatedWidget 简介 3D 旋转动画的实现 总结 前言 上一篇我们介绍了 Animation 和 AnimationController 的使用,这是最基本的动画构建类.但是,如果我们想构建一个可复用的动画组件,通过外部参数来控制其动画效果的时候,上一篇的方法就不太合适了.在 Flutter 中提供了 AnimatedWidget 组件用于构建可复用的动画组件.本篇我们用 AnimatedWidget 来实现组件的3D 旋转效果,如下图所示. AnimatedWidge

  • Android Flutter利用CustomPaint绘制基本图形详解

    目录 绘制矩形 绘制圆形 绘制椭圆 绘制任意形状 绘制弧形 总结 上一篇我们介绍了 CustomPaint 的基本概念和使用,可以看到 CustomPaint 其实和 前端的 Canvas基本上是一样的,实际上前端 Canvas 支持的绘制方法 CustomPaint 都支持,毕竟 CustomPaint 其实也是基于 Canvas 实现的.本篇我们来介绍 CustomPaint 基本图形的绘制. 绘制矩形 绘制矩形比较简单,方法定义如下: void drawRect(Rect rect, Pa

  • Flutter中数据库的使用教程详解

    在Flutter开发过程中,我门有时候需要对一些数据进行本地的持久化存储,使用sp文件形式虽然也能解决问题,但是有时数据量较大的时候,显然我们文件形式就不太合适了,这时候我们就需要使用数据库进行存储,我们知道在原生中有系统提供的轻量级sqlite数据库,在Flutter强大的生态环境中,也有这样一个数据库插件sqflite: ^2.0.2可以同时在Androud.iOS中进行数据库操作. 1. 创建数据库:这里我以存储我的搜索历史记录为例. 首先导入: import 'package:sqfli

  • Apache Cordova Android原理应用实例详解

    目录 前言 技术选型 技术原理 1. 如何本地加载url对应的资源 2. webview如何使用js调用app原生api 3. app原生api如何回调webview中的js 4. 多个plugin的情况 关于踩到的坑 1. 打包路径配置问题 2. success不回调问题 前言 从原理到应用复盘一下自己做过的所有项目,希望能让我自己过两年仍然能看懂现在写的代码哈哈.在项目里我只负责了Android的开发包括插件开发和集成,ios没摸到,有机会也得自己玩下,但是这篇文章不会接触. 技术选型 现在

随机推荐