前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Unity基础(18)-影音系统

Unity基础(18)-影音系统

作者头像
孙寅
发布2020-06-02 15:06:31
2K0
发布2020-06-02 15:06:31
举报
文章被收录于专栏:宜达数字
01-声音播放

声音播放组件

代码语言:javascript
复制
    // 声音组件(可手动添加,也可如下代码添加) 
    private AudioSource audio;
    // 声音片段(音频格式都支持)
    public AudioClip clip;
    void Start () {
         
        audio = this.gameObject.AddComponent<AudioSource>();
        // 一开始就播放
        audio.playOnAwake = true;
        // 声音片段
        audio.clip = clip;
        // 设置循环播放
        audio.loop = true;
        // 音量大小
        audio.volume = 0.2f;
        // 倍率播放(2倍播放)
        audio.pitch = 2f;
        // 静音播放
        audio.mute = true;
    }
    
    void Update () {
        if (Input.GetMouseButtonDown(0))
        {
            // 播放声音
            audio.Play();
        }
        if (Input.GetMouseButtonDown(1))
        {
            // 暂停播放
            audio.Pause();
        }
        if (Input.GetMouseButtonDown(2))
        {
            // 停止播放
            audio.Stop();
        }
    }
02-视频播放
  • PC端MovieTexture 优点:简单,高效的快速完成播放 缺点:此种方法无法应用于移动端。movietexture只能播放OGG和OVG
代码语言:javascript
复制
    // 视频片段 
    public MovieTexture video;
    // 声音片段
    public AudioClip clip;
    // 声音播放组件
    private AudioSource audio;
    
    void Start () {
        // 拿到Renderer的材质,设置里面的主贴图 = 视频片段
        this.gameObject.GetComponent<Renderer>().material.mainTexture = video;
        audio = this.gameObject.AddComponent<AudioSource>();
        audio.clip = clip; 
        // 循环播放
        video.loop = true;
        audio.loop = true;
        // 判断当前视频是否在播放
        if (video.isPlaying)
        {
            Debug.Log("判断视频是否播放");
        }
        // 视频的名字
        string name = video.name;
        Debug.Log(name);
    }   
    private void OnGUI()
    {
        if (GUILayout.Button("播放"))
        {
            audio.Play();
            video.Play();
        }
        if (GUILayout.Button("暂停"))
        {
            audio.Pause();
            video.Pause();
        }
        if (GUILayout.Button("停止"))
        {
            audio.Stop();
            video.Stop();
        }
    }
}
  • 移动端Handheld
    • 缺点: 可操作性非常差,几乎达不到我们想要的结果,而且也只支持全屏的普通视频的播放。
代码语言:javascript
复制
设置播放(视频路径,背景色,如何显示播放控件,如何缩放电影以适应屏幕)
PlayFullScreenMovie(string path, [DefaultValue("Color.black")] Color bgColor,[DefaultValue("FullScreenMovieControlMode.Full")] FullScreenMovieControlMode controlMode, [DefaultValue("FullScreenMovieScalingMode.AspectFit")] FullScreenMovieScalingMode scalingMode);
PlayFullScreenMovie(string path, Color bgColor, FullScreenMovieControlMode controlMode);
PlayFullScreenMovie(string path, Color bgColor);
PlayFullScreenMovie(string path);
// 设置样式方法(IOS,Android,列举)
SetActivityIndicatorStyle(ActivityIndicatorStyle style)
SetActivityIndicatorStyle(AndroidActivityIndicatorStyle style)
SetActivityIndicatorStyle(TizenActivityIndicatorStyle style)
// 获取当前的活动指示器样式。他获取的就是安卓苹果即列举的所有样式
GetActivityIndi​​catorStyle();
// 停止控制器(活动指示器)
StopActivityIndi​​cator();
// 触发设备振动
Vibrate();
// 启动操作系统活动指示器。为了让实际的动画生效,你通常需要等到这个帧结束。所以如果你希望活动指示器在同步操作中动画,请使用协程
StartActivityIndi​​cator

启动操作系统活动指示器:

代码语言:javascript
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Example2 : [MonoBehaviour](https://docs.unity3d.com/ScriptReference/MonoBehaviour.html)
{
    IEnumerator Load()
    {
        #if UNITY_IPHONE
        Handheld.SetActivityIndicatorStyle(iOS.ActivityIndicatorStyle.Gray);
        #elif UNITY_ANDROID
        Handheld.SetActivityIndicatorStyle(AndroidActivityIndicatorStyle.Small);
        #elif UNITY_TIZEN
        Handheld.SetActivityIndicatorStyle(TizenActivityIndicatorStyle.Small);
        #endif
        Handheld.StartActivityIndicator();
        yield return new WaitForSeconds(0);
        SceneManager.LoadScene("My Next Scene");
    }

    void OnGUI()
    {
        if (GUI.Button(new Rect(10, 10, 200, 200), "Load!"))
            StartCoroutine(Load());
    }
}
  • FullScreenMovieControlMode 如何显示播放控件枚举

FullScreenMovieControlMode

  • FullScreenMovieScalingMode 缩放电影以适应屏幕枚举

FullScreenMovieScalingMode

  • AndroidActivityIndicatorStyle : 安卓设备上的样式 如下:

安卓平台

  • ActivityIndicatorStyle iOS设备上样式 如下:

iOS平台样式

  • TizenActivityIndi​​catorStyle

列举样式

注意点: 将视频文件放置在Assets/StreamingAssets/路径下,经测试.MP4可用。最好通过网络加载的方式进行下载,避免打包程序过大。用完设置一个保存时间,一个月或者7天删除。

StreamingAssets

代码语言:javascript
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Handle : MonoBehaviour {
        string path;
    void Start () {
        path = "02.mp4";

        Handheld.StartActivityIndicator();
        Handheld.Vibrate();
    }
    private void OnGUI()
    {
        if(GUILayout.Button("全屏播放"))
         {
            Handheld.PlayFullScreenMovie(path,Color.black,FullScreenMovieControlMode.Full);
        }
        if (GUILayout.Button("显示控件最少的播放"))
        {
            Handheld.PlayFullScreenMovie(path, Color.black, FullScreenMovieControlMode.Minimal);
        }
        if (GUILayout.Button("不显示控件的播放"))
        {
            Handheld.PlayFullScreenMovie(path, Color.black, FullScreenMovieControlMode.Hidden);
        }
        if (GUILayout.Button("不显示控件输入取消播放"))
        {
            Handheld.PlayFullScreenMovie(path, Color.black, FullScreenMovieControlMode.CancelOnInput);
        }
    }
  • 全能VideoPlayer (Unity5.6之后) Unity5.6后,结合之前Unity特别难受的播放器,推出了新的VideoPlayer。支持大部分格式,无需转码。

VideoPlayer组件

  • 属性

属性

属性

属性

代码语言:javascript
复制
using UnityEngine;
using UnityEngine.Video;

public class VideoScripts : MonoBehaviour {

    private VideoPlayer videoPlayer;
    public VideoClip clip;
    private AudioSource audioSource;
    // Use this for initialization
    void Start () {
        videoPlayer = this.gameObject.AddComponent<VideoPlayer>();
        audioSource = this.gameObject.AddComponent<AudioSource>();

        videoPlayer.playOnAwake = false;
        audioSource.playOnAwake = false;

        // 设置输出模式
        videoPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource;

        // 如果使用VideoPlayer.audioOutputMode选择此音频目标,则设置将接收指定音轨音频样本的AudioSource
        videoPlayer.SetTargetAudioSource(0, audioSource);

        // 一开始没有声音就可以使用此方法
        videoPlayer.EnableAudioTrack(0, true);

        Debug.Log(videoPlayer.IsAudioTrackEnabled(0));
    }
    private void OnGUI()
    {
        if (GUILayout.Button("播放"))
        {
            videoPlayer.clip = clip;
            videoPlayer.Play();
            Debug.Log(videoPlayer.IsAudioTrackEnabled(0));
        }
        if (GUILayout.Button("暂停"))
        {
            videoPlayer.Pause();
        }
        if (GUILayout.Button("停止"))
        {
            videoPlayer.Stop();
        }
        if (GUILayout.Button("3倍速度播放"))
        {
            videoPlayer.playbackSpeed = 3f;
        }
    }
}

方法

事件

代理

  • iOS原生视频播放
代码语言:javascript
复制
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();  
  
    void Start () {   
         //视频要放在Assets\StreamingAssets\ 路径下面  
         setIosVideoUrl("test.mp4","当前挂载脚本物体名称"); //这里就可以直接调用  
         setIosVideoRect(20,20,200,200);  
         VideoPlay();   
    }        
}  

ios里面调用视频播放的接口代码

代码语言:javascript
复制
#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];  
}  

视频播放代码

代码语言:javascript
复制
#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  
代码语言:javascript
复制
#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  
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 01-声音播放
  • 02-视频播放
相关产品与服务
云点播
面向音视频、图片等媒体,提供制作上传、存储、转码、媒体处理、媒体 AI、加速分发播放、版权保护等一体化的高品质媒体服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档