版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36848370/article/details/82594162
1.为什么要调用ios原生视播放
unity 虽然有播放视频的方法
Handheld.PlayFullScreenMovie("test.mp4", Color.black, FullScreenMovieControlMode.CancelOnInput);
但是这个不能设置 大小 ,播放状态 等 局限性很大
2.使用ios AVPlayer 播放视频
1.unity中的c#代码
上面是封装到一个类里
其实可以直接调用
比如你unity里面一个物体上挂了一个脚本
using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;
public class NewBehaviourScript : MonoBehaviour {
[DllImport("__Internal")] //声明是调用ios代码
private static extern void setIosVideoUrl(string url,string objName);
[DllImport("__Internal")]
private static extern void setIosVideoRect(int left,int top,int width,int height);
[DllImport("__Internal")]
private static extern void VideoPlay();
// Use this for initialization
void Start () {
//视频要放在Assets\StreamingAssets\ 路径下面
setIosVideoUrl("101.mp4","当前挂载脚本物体名称"); //这里就可以直接调用
setIosVideoRect(20,20,200,200);
VideoPlay();
}
// Update is called once per frame
void Update () {
}
}
2.ios里面调用视频播放的接口代码
#include <string>
#import "AVPlayerController.h"
using namespace std;
extern "C"{
void setIosVideoUrl(char* url,char* objName); //这个方法正好对应上面c#代码方法 注意c#是string这里是char*
void setIosVideoRect(int left,int top,int width,int height);
void VideoPlay();
void VideoPause();
void VideoResume();
void VideoStop();
void VideoReplay();
void VideoRelease();
}
void setIosVideoUrl(char* url,char* objName){ <pre name="code" class="csharp">
// unity路径下视频路径是Assets\StreamingAssets下 打包到ios路径变成Data\Raw下了 这里做了一下处理
//把 101.mp4 改成 Data/Raw/101.mp4
AVPlayerController * avp = [AVPlayerController shareInstance];
NSString* str = [NSString stringWithCString:url encoding:NSUTF8StringEncoding];
NSLog(@"AA --- %@",str);
NSString* str3 = [NSString stringWithCString:objName encoding:NSUTF8StringEncoding];
NSLog(@"BB --- %@",str3);
NSString *topStr = @"Data/Raw/";
NSString *strAdd = [topStr stringByAppendingString:str];
NSString *strUrl = [strAdd stringByReplacingOccurrencesOfString:@".mp4" withString:@""];
NSLog(@"UUU --- %@",strUrl);
[avp setURL:strUrl UnityObj:objName];
}
void setIosVideoRect(int left,int top,int width,int height){
AVPlayerController * avp = [AVPlayerController shareInstance];
[avp setRect:left/2 TOP:top/2 WIDTH:width/2 HEIGHT:height/2]; //这里我除以2是做了特殊处理 可以不除以2
NSLog(@"left:%d,top:%d,width:%d,height:%d",left/2,top/2,width/2,height/2);
}
void VideoPlay(){
AVPlayerController * avp = [AVPlayerController shareInstance];
[avp play];
}
void VideoPause(){
AVPlayerController * avp = [AVPlayerController shareInstance];
[avp pause];
}
void VideoRelease(){
AVPlayerController * avp = [AVPlayerController shareInstance];
[avp removePlayer];
}
3.视频播放代码
#import <AVFoundation/AVFoundation.h>
#import <Foundation/Foundation.h> //这是要引入的头文件
@interface AVPlayerController : NSObject
+(id)shareInstance; //静态方法 相当于c#中的单列 (这个类只要初始化一次就可以了)
@property (nonatomic,strong) AVPlayer *avPlayer;//播放器对象
@property (nonatomic,strong) AVPlayerLayer* playerLayer;
@property (nonatomic,strong) AVPlayerItem* playerItem;
@property (nonatomic,readwrite) float playerDuration;
@property (nonatomic,strong) NSString* unityObjectName;
- (void)setURL:(NSString*)videoUrl UnityObj:(char*)objName;
- (void)setRect:(int)left TOP:(int)top WIDTH:(int)width HEIGHT:(int)height;
- (void)play;
- (void)pause;
- (void)removePlayer;
- (void)playbackFinished:(NSNotification *)notification;
- (bool)isPlaying;
@end
.m
#import "AVPlayerController.h"
static AVPlayerController *avp = nil;
@implementation AVPlayerController
+(id)shareInstance{
if(avp == nil){
avp = [[super allocWithZone:nil]init];
}
return avp;
}
+(id)allocWithZone:(NSZone *)zone{
return [AVPlayerController shareInstance];
}
//- (void) dealloc{
// //移除播放完成通知
// [[NSNotificationCenter defaultCenter] removeObserver:self];
//}
- (void)setURL:(NSString*)videoUrl UnityObj:(char*)objName{ //这个播放方法想了解 可以百度搜索下
NSString *path=[[NSBundle mainBundle] pathForResource:videoUrl ofType:@"mp4"];
NSURL* movieURL = [NSURL fileURLWithPath:path];
AVAsset* movieAsset = [AVURLAsset URLAssetWithURL:movieURL options:nil];
self.playerItem = [AVPlayerItem playerItemWithAsset:movieAsset];
self.avPlayer = [AVPlayer playerWithPlayerItem:self.playerItem];
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer];
self.playerLayer.videoGravity = AVLayerVideoGravityResize;
[UnityGetGLViewController().view.layer addSublayer:self.playerLayer];//注意 这个方法很重要(把ios视图添加到unity中)
self.unityObjectName = [NSString stringWithCString:objName encoding:NSUTF8StringEncoding];
[self addNotification];
CMTime duration = self.avPlayer.currentItem.asset.duration;
float seconds = CMTimeGetSeconds(duration);
self.playerDuration = seconds;
NSLog(@"总时长%.2fs.",seconds);
}
- (void)setRect:(int)left TOP:(int)top WIDTH:(int)width HEIGHT:(int)height{ //这个方法设置视频位置和长宽
self.playerLayer.frame = CGRectMake(left, top, width, height);
}
- (void)play{
[self.avPlayer play];
}
- (void)pause{
[self.avPlayer pause];
}
- (bool)isPlaying{
if(self.avPlayer.rate == 0){
NSLog(@"当前状态:暂停");
return false;
}
if(self.avPlayer.rate == 1){
NSLog(@"当前状态:播放");
return true;
}
return false;
}
-(void)addNotification{
//给AVPlayerItem添加播放完成通知 (不执行? 擦又可以了)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.avPlayer.currentItem];
//这里设置每秒执行一次 用这个方法代替播放完成通知 (上面可以 暂时弃用)
// [self.avPlayer addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
// float current=CMTimeGetSeconds(time);
//// NSLog(@"%f",current);
// if(current >= self.playerDuration)
// {
// NSLog(@"视频播放完成");
// }
// }];
}
-(void)playbackFinished:(NSNotification *)notification{
NSLog(@"video play finished!");
const char* unityObjName = [self.unityObjectName UTF8String];
UnitySendMessage(unityObjName, "OSVideoCallback", "EVENT_COMPLETED");//ios发送消息告诉unity视频播放完成
}
- (void)removePlayer{
[self.playerLayer removeFromSuperlayer];
self.playerLayer = nil;
self.avPlayer = nil;
self.playerItem = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
self.playerDuration = 0;
}
@end
3.具体代码网盘链接
http://pan.baidu.com/s/1jIDCRGE