文章目录

  • 前言
  • 一、工作背景
  • 二、工作步骤
    • 1.IOS部分
    • 2.Android部分
    • 3.导出打包测试
  • 总结

前言

最近需要开发app中的视频播放功能,首先要从系统相册中选择视频,然后将其在app中全屏播放。


一、工作背景

首先在unity中搭建了一个简单的平台,一个按钮和一个videoplayer物体。videoplayer使用的是unity自带的。
在button上挂了一个脚本,用来监听点击动作。通过判断不同的平台类型,安排对应的操作。
直接上代码 内联代码片

// unity端的代码
//定义相关的参数public Button btn;public GameObject m_videoPlayer;//public Image ImageView;AndroidJavaObject jo;[DllImport("__Internal")]private static extern void IOS_OpenAlbum();//点击按钮public void Start(){//点击按钮打开系统相册Debug.Log("点击了打开相册按钮");//在工程的开始阶段还是可以采用访问网页的形式上传视频的。
#if UNITY_EDITORDebug.Log("首先判断当前是unity编辑器,ios环境还是安卓环境,暂不做任何动作");m_videoPlayer.GetComponentInChildren<PlayChoosedVideo>().urlNetWork = @"/Downloads/recording_2021_04_11_18_12_41_718.MP4";AwakeAndCallUnity();
#elif UNITY_IOSDebug.Log("当前是ios环境,将打开iphone中的相册");AwakeAndCallIOS();
#elif UNITY_ANDROIDDebug.Log("当前是Android环境,将打开安卓或华为手机中的相册");AwakeAndCallAndroid();
#endif}//平台是unity editorprivate void AwakeAndCallUnity(){btn.onClick.AddListener(delegate {m_videoPlayer.GetComponentInChildren<PlayChoosedVideo>().GoToPlayVideo();});}//平台是ios则运行ios唤醒和召唤private void AwakeAndCallIOS(){btn.onClick.AddListener(IOS_OpenAlbum);}//平台是android则运行安卓唤醒和召唤private void AwakeAndCallAndroid(){AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");jo = jc.GetStatic<AndroidJavaObject>("currentActivity");btn.onClick.AddListener(delegate {CallAndroid();Debug.Log("点击按钮");});}void CallAndroid(){jo.Call("startPhoto");Debug.Log("向安卓提出操作请求");}public void message(string str){#if UNITY_ANDROIDDebug.Log("安卓传来信息:" + str);StartCoroutine(LoadTexturePreview(str));
#elif UNITY_IOSDebug.Log("苹果传来信息:" + str);StartCoroutine(LoadTexturePreview(str));
#endif}IEnumerator LoadTexturePreview(string path){yield return 0;Debug.Log("视频地址:" + path);//将该字符串地址传递给场景中的播放函数m_videoPlayer.GetComponentInChildren<PlayChoosedVideo>().urlNetWork = path;m_videoPlayer.GetComponentInChildren<PlayChoosedVideo>().GoToPlayVideo();}
}

视频播放部分的代码,我挂在了videoplayer物体上。
下面展示一些 内联代码片

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;public class PlayChoosedVideo : MonoBehaviour
{public GameObject m_VideoPLayer;//public Slider sliderVolume;//public Slider sliderVideo;//是否拿到视频总时长public bool isShow;//时 分的转换private int hour, min;private float time;private float time_Count;private float time_Current;private bool isVideo;private VideoPlayer vPlayer;//private AudioSource source;public string urlNetWork;public void GoToPlayVideo(){Init(urlNetWork);}private void Init(string url){isVideo = true;isShow = true;time_Count = 0;time_Current = 0;//sliderVideo.value = 0;vPlayer = m_VideoPLayer.GetComponentInChildren<VideoPlayer>();//设置为URL模式vPlayer.source = VideoSource.Url;vPlayer.url = url;//vPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource;//vPlayer.SetTargetAudioSource(0, source);vPlayer.prepareCompleted += OnPrepared;vPlayer.Prepare();}void OnPrepared(VideoPlayer player){player.Play();//sliderVideo.onValueChanged.AddListener(delegate { AdjustVideoProgress(sliderVideo.value); });}}

二、工作步骤

1.IOS部分

unity与ios交互的逻辑就是打开ios中的函数,传递代码,我们需要将ios的系统相册打开,选择其中的视频文件,然后返回给unity该视频文件的路径,然后在unity中将该路径的视频文件播放出来。
这里就需要在plugins/ios文件夹里增加ios的.h和.m文件,在生成的时候unity会自动将其发送给xcode。
.h的代码 内联代码片

#ifndef IOSCameraAlbumController_h
#define IOSCameraAlbumController_h
//import 引用头文件 相当于Using
#import<QuartzCore/CADisplayLink.h>
//声明一个IOSCameraController类  继承自UIViewController <>里面是是协议/代理的调用声明 可以理解为c#的接口
@interface
IOSCameraAlbumController : UIViewController<UIImagePickerControllerDelegate,UINavigationControllerDelegate>
@end#endif /* IOSCameraAlbumController_h */

.m的代码 内联代码片

#import <Foundation/Foundation.h>
#import "IOSCameraAlbumController.h"
#import <MobileCoreServices/MobileCoreServices.h>
#import <Photos/Photos.h>@implementation IOSCameraAlbumController-(void)OpenTarget:(UIImagePickerControllerSourceType) type{//创建UIImagePickerController实例UIImagePickerController *picker;picker = [[UIImagePickerController alloc] init];//设置代理picker.delegate = self;//是否允许编辑 (默认为NO)picker.allowsEditing = YES;//设置照片的来源// UIImagePickerControllerSourceTypePhotoLibrary,      // 来自图库// UIImagePickerControllerSourceTypeCamera,            // 来自相机// UIImagePickerControllerSourceTypeSavedPhotosAlbum   // 来自相册picker.sourceType = type;picker.mediaTypes = @[@"public.movie"];
//    picker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypePhotoLibrary];[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {//相册访问权限if (status == PHAuthorizationStatusAuthorized) {NSLog(@"Authorized");}else{NSLog(@"Denied or Restricted");}}];//这里需要判断设备是iphone还是ipad  如果使用的是iphone并没有问题 但是如果 是在ipad上调用相册获取图片 会出现没有确定(选择)的按钮 所以这里判断//了一下设备,针对ipad 使用另一种方法 但是这种方法是弹出一个界面 并不是覆盖整个界面 需要改进 试过另一种方式 重写一个相册界面//(QQ的ipad选择头像的界面 就使用了这种方式 但是这里我们先不讲 (因为我也不太懂 但是我按照简书的一位老哥的文章写出来了 这里放一下这个简书的链接//https://www.tlbyxzcx.com)if (picker.sourceType == UIImagePickerControllerSourceTypePhotoLibrary &&[[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {// 设置弹出的控制器的显示样式picker.modalPresentationStyle = UIModalPresentationPopover;//获取这个弹出控制器UIPopoverPresentationController *popover = picker.popoverPresentationController;//设置代理popover.delegate = self;//下面两个属性设置弹出位置popover.sourceRect = CGRectMake(0, 0, 0, 0);popover.sourceView = self.view;//设置箭头的位置popover.permittedArrowDirections = UIPopoverArrowDirectionAny;//展示选取照片控制器[self presentViewController:picker animated:YES completion:nil];} else {//展示选取照片控制器[self presentViewController:picker animated:YES completion:^{}];}
}//选择资源以后,获取资源路径
//控制器不会自己dismiss 需要我们手动在相应的地方实现
//这两个代理方法只会收到其中一个,取决于用户的点击情况
//结束采集之后 之后怎么处理都在这里写 通过Infokey取出相应的信息  Infokey可在进入文件中查看
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey, id> *)info{//查看是视频还是照片  public.image 或 public.movieNSString * mediaType = [info objectForKey:UIImagePickerControllerMediaType];if ([mediaType isEqualToString:@"public.image"]) {//照片}if ([mediaType isEqualToString:@"public.movie"]) {//视频NSLog(@"found a video");// 获取视频的名称NSString *videoPath = [NSString stringWithFormat:@"%@",[info objectForKey:UIImagePickerControllerMediaURL]];NSLog(@"%@", videoPath);NSString *sendMessageToUnity = [[NSString alloc]init];sendMessageToUnity = [NSString stringWithString:videoPath];NSInteger leng = [sendMessageToUnity length];NSLog(@"%ld",(long)leng);const char *char_content = [sendMessageToUnity cStringUsingEncoding:NSASCIIStringEncoding];UnitySendMessage("ClickOpenAlbum","message",char_content);[picker dismissModalViewControllerAnimated:YES];}[self dismissViewControllerAnimated:picker completion:nil];
}- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{[self dismissViewControllerAnimated:picker completion:nil];
}@end//由于C++编译器需要支持函数的重载,会改变函数的名称,因此dll的导出函数通常是标准C定义的。
//这就使得C和C++的互相调用变得很常见。但是有时可能又会直接用C来调用,不想重新写代码,
//让标准C编写的dll函数定义在C和C++编译器下都能编译通过,通常会使用以下的格式:(这个格式在很多成熟的代码中很常见)
#if defined(__cplusplus)
extern "C" {#endifvoid IOS_OpenAlbum(){IOSCameraAlbumController *app = [[IOSCameraAlbumController alloc]init];UIViewController *vc = UnityGetGLViewController();[vc.view addSubview:app.view];[app OpenTarget:UIImagePickerControllerSourceTypePhotoLibrary];}
#if defined(__cplusplus)
}
#endif

注意要引入photo框架,否则xcode生成的时候会报错。

2.Android部分

android需要在库里新建java包package,我选择新建了一个com.refreshalbum.callandroid的包,然后在这个包里建了名为CallAlbum.java的类,然后更改了AndroidManifest清单,让这个类可以通过unity呼唤,然后返回视频文件的路径。
直接上类的代码 内联代码片

package com.refreshalbum.callandroid;import android.Manifest;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;
// 要注意这个地方继承 UnityPlayerActivitypublic class CallAlbum extends UnityPlayerActivity{@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 获取存储权限,不然的话无法获取图片if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, 100);}}// unity点击按钮触发这个方法public void startPhoto() {Log.d("unity","打开相册");Intent intent = new Intent(Intent.ACTION_PICK);intent.setType("video/*");startActivityForResult(intent, 111);  // 第二个参数是请求码}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (resultCode == RESULT_OK) {switch (requestCode) {case 111:  // 请求码Log.d("Unity", "相册返回");UnityPlayer.UnitySendMessage("ClickOpenAlbum", "message", parseUri(data));Log.d("unity", parseUri(data));break;}}}public String parseUri(Intent data) {Uri uri = data.getData();String imagePath;// 第二个参数是想要获取的数据Cursor cursor = getContentResolver().query(uri, new String[]{MediaStore.Images.ImageColumns.DATA},null, null, null);if (cursor == null) {imagePath = uri.getPath();} else {cursor.moveToFirst();// 获取数据所在的列下标int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);imagePath = cursor.getString(index);  // 获取指定列的数据cursor.close();}return imagePath;  // 返回图片地址}
}

3.导出打包测试

在build setting中export导出AS工程和Xcode工程进行测试,我这里没有报出什么错,直接成功生成。

总结

上述方法已经经过测试,完全有效,希望对其他小伙伴有所帮助。

记录unity视频选择与播放_IOSAndroid相关推荐

  1. 2022-11-10 工作记录--HTML-video视频铺满播放

    HTML-video视频铺满播放 一.实现效果 ⭐️ 1.未铺满播放 ❎ 2.铺满播放 ✅ 二.实现代码 ⭐️ 以react为例 1.未铺满播放 ❎ homePage.jsx import React ...

  2. unity 使用ump插件播放视频 ,打包发布后黑屏或者在别人电脑上运行黑屏,解决方案

    unity 使用ump插件播放视频 ,打包发布后黑屏或者在别人电脑上运行黑屏,解决方案. ump插件下载 最近在项目里面 需要接入海康监控 并在unity中显示,我选择使用ump 插件播放视频, 刚开 ...

  3. 记录--浏览器插件分享(视频倍速播放插件)

    记录–浏览器插件分享(视频倍速播放插件) 最近看视频的时候偶然有发现视频倍速播放的几个方法,跟大家分享一下. 第一种 这种是最简单的,我们直接使用火狐浏览器就可以倍速播放视频. 如下图,在视频加载好后 ...

  4. 【Unity】通过Plane播放视频存在的颜色偏暗的问题

    [Unity]通过Plane播放视频存在的颜色偏暗的问题 背景:采用VideoPlayer插件选择MaterialOverride将视频在一个Plane上播放: 描述:Plane上可以正常播放视频,但 ...

  5. 手机影音第十一天,显示视频缓冲,显示卡顿时的网速,播放系统视频时调用播放器的选择...

    代码已经托管到码云,有兴趣的小伙伴可以下载看看 https://git.oschina.net/joy_yuan/MobilePlayer 一.设置视频缓冲进度 显示视频播放进度的效果图如下:灰色的是 ...

  6. Unity中使用AVproVideo播放全景视频(HTCVIVE)

    Unity中使用HTCVIVE播放全景视频(AVProVideo插件) 1.前言 刚入职第一周做了一项目小demo,接下来给大家分享一下我的感悟吧! 1.1.Unity中播放全景视频有很多种方法,但都 ...

  7. 视频和语音播放(进行中)

    点播,直播,VR(录制音频和视频,在线的和本地的),视频播放器和音乐播放器(播放音乐和视频),视频和语音 VideoView并不是支持播放所有格式的视频,它仅支持mp4和3gp格式的文件,实际上它的本 ...

  8. WebRTC音视频采集和播放示例及MediaStream媒体流解析

    WebRTC音视频采集和播放示例及MediaStream媒体流解析 目录 示例代码--同时打开摄像头和麦克风,并在页面显示画面和播放捕获的声音 API解析 mediaDevices MediaStre ...

  9. 直播平台软件开发中选择点播播放器哪家强?

    直播平台软件开发中选择点播播放器哪家强? 太长不看版 这里选择了开源播放器IjkPlayer和直播云厂商播放器PLDroidPlayer作为测试样本. 数据统计 软硬编码 IjkPlayer PLDr ...

最新文章

  1. 数据结构(算法)-线性表2(单链表)
  2. CentOS安装scrot记
  3. lucene7.5的数据结构
  4. 线性回归中oracle性质,66.Oracle数据库SQL开发之 高级查询——使用线性回归函数...
  5. 动态规划求解限时采药问题(洛谷P1048题题解,Java语言描述)
  6. 软考高项信息系统项目管理工程师自考500元搞定攻略
  7. win7 建立无线wifi执点全过程
  8. 数据安全:英国公司泄露超过100万人的指纹和面部识别数据
  9. 【数据结构和算法】广度优先BFS遍历图(树的层序遍历的拓展)
  10. 【Proteus仿真8086】将IO接口电路封装成子电路CCT001
  11. 使用N2N软件远程管理DLAP221设备
  12. java 主项目 子项目_java web项目自动管理子项目,以及子项目打包
  13. Matlab论文插图绘制模板第78期—进阶词云图
  14. 华为虚拟化FusionCompute知识点总结
  15. JSP+servlet+mysql个人博客系统
  16. echarts 环状图中添加图片
  17. POJ1837 DP
  18. oracle餐厅网络点餐系统_点餐系统产品演示
  19. 跳妹儿学编程之ScratchJr(一):高级软件工程师告诉你什么是儿童编程,小孩要不要学儿童编程?
  20. 关于WM_ERASEBKGND和WM_PAINT的深刻理解

热门文章

  1. 归一化,正则化等梯度下降优化详解(4)机器学习
  2. 一机一码可以让加密的视频只能在一台设备上播放吗?
  3. 洋葱IPO破发,跨境电商真不好做
  4. 苹果cms v10 采集视频资源图片不显示加载慢修复方法
  5. CRM系统-----学员管理系统
  6. 委托与事件_从有趣的例子出发去解析
  7. ArcGis克里金斯插值详解
  8. 制作图文混排网页学习笔记
  9. 微信PC客户端一打开就崩溃问题解决
  10. 奥数计算机竞赛试题,三年级奥数竞赛试题 三年级信息技术试题.doc