首页 > 其他分享 >flutter 添加原生IOS 播放器

flutter 添加原生IOS 播放器

时间:2023-12-28 13:35:24浏览次数:21  
标签:播放器 viewId IOS let arguments import messenger flutter tempView

定义播放器

FlutterAVPlayer.swift


import Foundation
import AVKit
import MediaPlayer
import Flutter

class FlutterAVPlayer: NSObject, FlutterPlatformView {
    private var _flutterAVPlayerViewController : AVPlayerViewController;
    
    init(frame:CGRect,
          viewIdentifier: CLongLong,
          arguments: Dictionary<String, Any>,
          binaryMessenger: FlutterBinaryMessenger) {
        _flutterAVPlayerViewController = AVPlayerViewController()
        _flutterAVPlayerViewController.viewDidLoad()
        if let urlString = arguments["url"] {
            let item = AVPlayerItem(url: URL(string: urlString as! String)!)
            _flutterAVPlayerViewController.player = AVPlayer(playerItem: item)
        } else if let filePath = arguments["file"] {
            let appDelegate = UIApplication.shared.delegate as! FlutterAppDelegate
            let vc = appDelegate.window.rootViewController as! FlutterViewController
            let lookUpKey = vc.lookupKey(forAsset: filePath as! String)
            if let path = Bundle.main.path(forResource: lookUpKey, ofType: nil) {
                let item = AVPlayerItem(url: URL(fileURLWithPath: path))
                _flutterAVPlayerViewController.player = AVPlayer(playerItem: item)
            }
        }
        _flutterAVPlayerViewController.player!.play()
    }
    func view() -> UIView {
        return _flutterAVPlayerViewController.view;
    }
    
}


选择器

FlutterRoutePickerView.swift

import Foundation
import AVKit
import MediaPlayer
import Flutter

class FlutterRoutePickerView: NSObject, FlutterPlatformView {
    private var _flutterRoutePickerView : UIView;
    private var _delegate: AVRoutePickerViewDelegate?
    
    init(
        messenger: FlutterBinaryMessenger,
        viewId: Int64,
        arguments: Dictionary<String, Any>
    ) {
        if #available(iOS 11.0, *) {
            let tempView = AVRoutePickerView(frame: .init(x: 0.0, y: 0.0, width: 44.0, height: 44.0))
            if let tintColor = arguments["tintColor"] {
                let color = tintColor as! Dictionary<String, Any>
                tempView.tintColor = FlutterRoutePickerView.mapToColor(color)
            }
            if let tintColor = arguments["activeTintColor"] {
                let color = tintColor as! Dictionary<String, Any>
                tempView.activeTintColor = FlutterRoutePickerView.mapToColor(color)
            }
            if let tintColor = arguments["backgroundColor"] {
                let color = tintColor as! Dictionary<String, Any>
                tempView.backgroundColor = FlutterRoutePickerView.mapToColor(color)
            }
            
            if #available(iOS 13.0, *) {
                tempView.prioritizesVideoDevices = arguments["prioritizesVideoDevices"] as! Bool
            }
            
            _delegate = FlutterRoutePickerDelegate(viewId: viewId, messenger: messenger)
            tempView.delegate = _delegate
            
            _flutterRoutePickerView = tempView
        } else {
            let tempView = MPVolumeView(frame: .init(x: 0.0, y: 0.0, width: 44.0, height: 44.0))
            tempView.showsVolumeSlider = false
            _flutterRoutePickerView = tempView
        }
    }
    
    func view() -> UIView {
        return _flutterRoutePickerView
    }
    
    static func mapToColor(_ map: Dictionary<String, Any>) -> UIColor {
        return  UIColor.init(red: CGFloat(map["red"] as! Int) / 255,
                             green: CGFloat(map["green"] as! Int) / 255,
                             blue: CGFloat(map["blue"] as! Int) / 255,
                             alpha: CGFloat(map["alpha"] as! Int) / 255)
    }
}

class FlutterRoutePickerDelegate : NSObject, AVRoutePickerViewDelegate {
    let _methodChannel: FlutterMethodChannel

    init(viewId: Int64, messenger: FlutterBinaryMessenger) {
        _methodChannel = FlutterMethodChannel(name: "flutter_to_airplay#\(viewId)", binaryMessenger: messenger)
    }

    func routePickerViewWillBeginPresentingRoutes(_ routePickerView: AVRoutePickerView) {
        _methodChannel.invokeMethod("onShowPickerView", arguments: nil)
    }

    func routePickerViewDidEndPresentingRoutes(_ routePickerView: AVRoutePickerView) {
        _methodChannel.invokeMethod("onClosePickerView", arguments: nil)
    }
}

共享工厂

SharePlatformViewFactory.swift

import Foundation
import Flutter

class SharePlatformViewFactory: NSObject, FlutterPlatformViewFactory {
    let _messenger : FlutterBinaryMessenger

    init(messenger: FlutterBinaryMessenger & NSObjectProtocol) {
        _messenger = messenger
    }

    func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView {
        let argumens = args as! Dictionary<String, Any>;
        if let viewClass = argumens["class"] {
            let vc = viewClass as! String
            if vc == "AirplayRoutePicker" {
                let pickerView = FlutterRoutePickerView(messenger: _messenger, viewId: viewId, arguments: argumens)
                return pickerView
            }
            else if vc == "FlutterAVPlayerView" {
                let pickerView = FlutterAVPlayer(frame: frame, viewIdentifier: viewId, arguments: argumens, binaryMessenger: _messenger)
                return pickerView
            }
        }
        
        return UIView() as! FlutterPlatformView
    }
    
    func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
        return FlutterStandardMessageCodec.sharedInstance()
    }
}

注册插件

SwiftFlutterToAirplayPlugin.swift

import Flutter
import UIKit

 
public class SwiftFlutterToAirplayPlugin: NSObject, FlutterPlugin {
  public static func register(with registrar: FlutterPluginRegistrar) {
    registrar.register(
        SharePlatformViewFactory(messenger: registrar.messenger()),
        withId: "airplay_route_picker_view",
        gestureRecognizersBlockingPolicy: FlutterPlatformViewGestureRecognizersBlockingPolicy(rawValue: 0))
    
    registrar.register(
        SharePlatformViewFactory(messenger: registrar.messenger()),
        withId: "flutter_avplayer_view",
        gestureRecognizersBlockingPolicy: FlutterPlatformViewGestureRecognizersBlockingPolicy(rawValue: 0))
  }
}

最后一步委派插件

AppDelegate.swift

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
      let registrar:FlutterPluginRegistrar = self.registrar(forPlugin: "flutter_to_airplay")!
     SwiftFlutterToAirplayPlugin.register(with: registrar)
      
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

标签:播放器,viewId,IOS,let,arguments,import,messenger,flutter,tempView
From: https://www.cnblogs.com/guanchaoguo/p/17932474.html

相关文章

  • mpv:轻量强大的视频播放器
    入门-知乎中文文档快速下载进入官网安装页:https://mpv.io/installation/快速安装进入installer目录,管理员身份运行mpv-install.bat来安装,并关联文件类型快速使用右键暂停,双击全屏,滚轮音量快速配置主配置:创建D:\ProgramFiles\mpv\portable_config\mpv.conf快捷键:创......
  • Flutter常见库使用
    1、网络库diodio:^5.4.0import'package:dio/dio.dart';finaldio=Dio();voidgetHttp()async{finalresponse=awaitdio.get('https://dart.dev');print(response);}2、JSON解析json_serializable:^6.7.1json_annotation:^4.8.1bu......
  • idea flutter dart 代码不跳转 analyze 不起作用
    查看本地dartwheredart/opt/homebrew/bin/dart/Users/jimogangdan/soft/flutter/bin/dart两个版本不一样/opt/homebrew/bin/dart--versionDartSDKversion:3.1.3(stable)(TueSep2614:25:132023+0000)on"macos_arm64"/Users/jimogangdan/soft/flutter/b......
  • flutter常用的设计模式
    单例模式(SingletonPattern):确保一个类只有一个实例,并提供一个全局访问点。工厂模式(FactoryPattern):定义一个创建对象的接口,但让子类决定具体实例化哪个类;常用于创建组件、复杂对象等场景。抽象工厂模式(AbstractFactoryPattern):提供一个创建一系列相关或相互依赖对象的接口,而......
  • Flutter 中常用的缓存数据方式
    SharedPreferences:优点:使用简单,轻量级,适用于少量数据的缓存;缺点:不适合存储大型、结构化、复杂的数据;SQLite:优点:可以存储大量、结构化、复杂的数据,支持复杂的数据查询操作;缺点:比较复杂,需要学习SQL和数据库操作;Hive:优点:快速、可扩展,性能较好,适用于存储大量数据;缺点:不支持......
  • Flutter获取大文件MD5值的方法以及大文件实现分块上传和断点续传
    Flutter获取大文件MD5值的方法最近一直在搞flutter,有一个需求是将一个不到1G的大文件从App端上传到服务器,为了做文件校验所以要获取到文件的MD5。1.第一步首先获取到文件,并计算出文件大小和分快的数目Filefile=File(path);intfileSize=file.lengthSync();inttotalPart=......
  • 从零开始用 Axios 请求后端接口
    对于前端同学来说,请求后端接口是一个非常通用的东西。在十几年前的时候,我们还用Ajax去请求后端接口。但在2023年的今天,很多框架都很成熟了,我们有了更加快捷的方式——Axios框架。请求框架哪家强?对于使用Vue技术栈的同学来说,其实接口请求框架就三种:vue-resource、Axios、fe......
  • uniapp APP应用程序iOS没有上架到苹果应用商店如何整包更新?
    随着移动互联网的快速发展,uni-app作为一种跨平台开发框架,受到了广泛欢迎。然而,有时候开发者可能会遇到一个问题:如何为已经发布到苹果应用商店的uni-appAPP进行整包更新?尤其是当应用还没有上架到苹果应用商店时。铁蛋也收集整理了相关内容,今天将为你详细解答这一问题,帮助你顺利......
  • ionic在iOS16上遇到的一些问题,图片、图标不显示,样式不正常等
    近日,一个很久之前ionic5开发的APP的iOS版因为签名描述文件(profile、.mobileProvisioning)过期而不能使用了,所以需要重新创建一个描述文件,然后重新打包APP。但过程中却遇到了一系列的问题,特写此文记录下来。问题1,iOS打包遇到问题:在xcode的Signing&Capabilities面板中选择(导入)了......
  • axios之基本封装
    1.axios实例安装axios库npminstallaxiosoryarnaddaxiosorCDN<scriptsrc="https://unpkg.com/axios/dist/axios.min.js"></script>//引入importaxiosfrom'axios'//库importCookiesfrom'js-cookie'import{Notifi......