将视频内容播放到目标上。
内容可以是 VideoClip 导入资源,也可以是 URL(例如 file://
或 http://
.)。视频内容将投射到一个受支持的目标上,例如摄像机背景或 RenderTexture。
如果视频内容包括透明度,此透明度将出现在目标中,允许视频目标后面的对象可见。
电影文件格式支持说明
VideoPlayer 在其实现中使用原生音频和视频解码库,您有责任使用符合目标平台要求的视频。VideoClipImporter 提供了一个将 VideoClip 资源转码为 H.264 或 VP8 视频编解码器的选项,以及一些实验性选项(例如 Resolution)。这会将匹配的编解码器用于音频轨道:分别是 AAC 和 Vorbis。
另请参阅:VideoClipImporter.SetTargetSettings 和 VideoImporterTargetSettings.enableTranscoding。
您可以选择忽略此转码,而是改用已知受目标系统支持的视频,同时使用外部程序更精确地控制编码过程。在使用过程中,VideoClipImporter 编辑器会提供指导和警告,以更好地帮助您做出正确的格式和编码选择。
目前,必须遵循供应商建议,而且在旧版移动平台上尤其受到约束。例如,您在 Web 中找到的视频通常需要经过检查和相关操作,才能在运行在多个设备上的游戏环境中可靠地使用。以下是一些建议和已知限制的示例:
* Android:支持的媒体格式:。请参阅下方的附加说明。\
* Windows:H.264 视频解码器(请参阅“格式约束”)\
* iPhone 6-7:比较 iPhone 型号(请参阅“电视和视频”)
可用于硬件加速的本机支持的最优视频编解码器是 H.264,同时 VP8 作为可以在需要时使用的软件解码解决方案。在 Android 上,VP8 还支持使用本机库,因此也可以根据型号对硬件进行辅助。要在编码参数中查找的键值:
* Video Codec:H.264 或 VP8。\
* Resolution:例如:1280 x 720。\
* Profile:适用于 H.264。配置文件是一组功能和约束;供应商通常会指定此配置文件,例如“Baseline”或“Main”。请参阅here.\
* Profile Level:适用于 H.264。在一个给定配置文件中,级别会指定某些性能要求,例如“Baseline 3.1”。请参阅here.\
* Audio Codec:通常是 AAC(适用于使用 H.264 的 mp4 视频)或 Vorbis(适用于使用 VP8 的 webm 视频)。\
* Audio Channels:取决于平台。例如,针对 Android 的建议是立体声文件,但很多设备都接受 5.1。
关于 Android 的注意事项
* Support for resolutions above 640 x 360 is not available on all devices. Runtime checks are done to verify this and failures will cause the movie to not be played.
* For Jelly Bean/MR1, movies above 1280 x 720 or with more than 2 audio tracks will not be played due to bugs in the OS libraries.
* For Lollipop and above, any resolution or number of audio channels may be attempted, but will be constrained by device capabilities.
* The Vulkan graphics API is not yet supported.
* Format compatibility issues are reported in the adb logcat
output and are always prefixed with AndroidVideoMedia
.
* Also pay attention to device-specific error messages located near Unity's ones: they are not available to the engine, but often explains what the compatibility issue is.
以下部分演示了 VideoPlayer 的一些功能:
// Examples of VideoPlayer function
using UnityEngine;
public class Example : MonoBehaviour { void Start() { // Will attach a VideoPlayer to the main camera. GameObject camera = GameObject.Find("Main Camera");
// VideoPlayer automatically targets the camera backplane when it is added // to a camera object, no need to change videoPlayer.targetCamera. var videoPlayer = camera.AddComponent<UnityEngine.Video.VideoPlayer>();
// Play on awake defaults to true. Set it to false to avoid the url set // below to auto-start playback since we're in Start(). videoPlayer.playOnAwake = false;
// By default, VideoPlayers added to a camera will use the far plane. // Let's target the near plane instead. videoPlayer.renderMode = UnityEngine.Video.VideoRenderMode.CameraNearPlane;
// This will cause our scene to be visible through the video being played. videoPlayer.targetCameraAlpha = 0.5F;
// Set the video to play. URL supports local absolute or relative paths. // Here, using absolute. videoPlayer.url = "/Users/graham/movie.mov";
// Skip the first 100 frames. videoPlayer.frame = 100;
// Restart from beginning when done. videoPlayer.isLooping = true;
// Each time we reach the end, we slow down the playback by a factor of 10. videoPlayer.loopPointReached += EndReached;
// Start playback. This means the VideoPlayer may have to prepare (reserve // resources, pre-load a few frames, etc.). To better control the delays // associated with this preparation one can use videoPlayer.Prepare() along with // its prepareCompleted event. videoPlayer.Play(); }
void EndReached(UnityEngine.Video.VideoPlayer vp) { vp.playbackSpeed = vp.playbackSpeed / 10.0F; } }
MovieTexture 迁移注意事项
由于 VideoPlayer 与传统电影播放解决方案 MovieTexture 存在根本的不同,我们提供了一些示例来帮助您使用 MovieTexture 将项目迁移到新的 VideoPlayer 解决方案。
播放电影示例:
MovieTexture:
public class PlayMovie : MonoBehaviour { public AudioClip movieAudioClip; public MovieTexture movieTexture;
void Start() { var audioSource = gameObject.AddComponent<AudioSource>(); audioSource.clip = movieAudioClip; }
void Update() { if (Input.GetButtonDown("Jump")) { var audioSource = GetComponent<AudioSource>(); GetComponent<Renderer>().material.mainTexture = movieTexture;
if (movieTexture.isPlaying) { movieTexture.Pause(); audioSource.Pause(); } else { movieTexture.Play(); audioSource.Play(); } } } }
VideoPlayer:
public class PlayMovie : MonoBehaviour { public VideoClip videoClip;
void Start() { var videoPlayer = gameObject.AddComponent<VideoPlayer>(); var audioSource = gameObject.AddComponent<AudioSource>();
videoPlayer.playOnAwake = false; videoPlayer.clip = videoClip; videoPlayer.renderMode = VideoRenderMode.MaterialOverride; videoPlayer.targetMaterialRenderer = GetComponent<Renderer>(); videoPlayer.targetMaterialProperty = "_MainTex"; videoPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource; videoPlayer.SetTargetAudioSource(0, audioSource); }
void Update() { if (Input.GetButtonDown("Jump")) { VideoPlayer vp = GetComponent<VideoPlayer>();
if (vp.isPlaying) { vp.Pause(); } else { vp.Play(); } } } }
下载电影示例:
MovieTexture:
public class DownloadMovie : MonoBehaviour { void Start() { StartCoroutine(GetMovieTexture()); }
IEnumerator GetMovieTexture() { using (var uwr = UnityWebRequestMultimedia.GetMovieTexture("http://myserver.com/mymovie.ogv")) { yield return uwr.SendWebRequest(); if (uwr.isNetworkError || uwr.isHttpError) { Debug.LogError(uwr.error); yield break; }
MovieTexture movie = DownloadHandlerMovieTexture.GetContent(uwr);
GetComponent<Renderer>().material.mainTexture = movie; movie.loop = true; movie.Play(); } } }
VideoPlayer:
public class DownloadMovie : MonoBehaviour { void Start() { var vp = gameObject.AddComponent<VideoPlayer>(); vp.url = "http://myserver.com/mymovie.mp4";
vp.isLooping = true; vp.renderMode = VideoRenderMode.MaterialOverride; vp.targetMaterialRenderer = GetComponent<Renderer>(); vp.targetMaterialProperty = "_MainTex";
vp.Play(); } }
controlledAudioTrackMaxCount | 可以控制的最大音频轨道数量。 |
aspectRatio | 定义如何拉伸视频内容以填充目标区域。 |
audioOutputMode | 嵌入在视频中的音频的目标。 |
audioTrackCount | 在当前配置的数据源中找到的音频轨道数量。 |
canSetDirectAudioVolume | 当前平台和视频格式是否支持直接输出音量控制。(只读) |
canSetPlaybackSpeed | 播放速度是否可以更改。(只读) |
canSetSkipOnDrop | 确定是否要 VideoPlayer 跳帧以追上当前时间。(只读) |
canSetTime | 是否可以使用 time 或 timeFrames 属性更改当前时间。(只读) |
canSetTimeSource | 是否可以更改 VideoPlayer 遵循的时间源。(只读) |
canStep | 如果 VideoPlayer 可以使视频内容前进,则返回 true。(只读) |
clip | VideoPlayer 正在播放的剪辑。 |
controlledAudioTrackCount | 此 VideoPlayer 将控制的音频轨道数量。其他音频轨道将被调为静音。最多允许 64 个音频轨道。 在播放 URL 时,无法预先知道音频轨道的实际数量,这就是此值独立于 VideoPlayer.audioTrackCount 属性的原因。 |
externalReferenceTime | VideoPlayer 用于纠正其偏差的外部时钟的参考时间。 |
frame | VideoPlayer 当前显示的帧索引。 |
frameCount | 当前视频内容中的帧数。 |
frameRate | 剪辑或 URL 的帧率(以帧或秒为单位)。(只读)。 |
isLooping | 确定当 VideoPlayer 到达剪辑的结尾时是否从头开始播放。 |
isPlaying | 是否正在播放内容。(只读) |
isPrepared | VideoPlayer 是否已完成待播放内容的准备工作。(只读) |
playbackSpeed | 基本播放速率的增加倍数。 |
playOnAwake | 内容是否会在组件被唤醒后立即开始播放。 |
renderMode | 将绘制视频内容的位置。 |
sendFrameReadyEvents | 启用 frameReady 事件。 |
skipOnDrop | 是否允许 VideoPlayer 跳帧以追上当前时间。 |
source | VideoPlayer 用于播放的源。 |
targetCamera | 当 VideoPlayer.renderMode 设置为 VideoRenderMode.CameraFarPlane 或 VideoRenderMode.CameraNearPlane 时,要在其中绘制资源的摄像机组件。 |
targetCamera3DLayout | 源视频媒体中包含的 3D 内容的类型。 |
targetCameraAlpha | 目标摄像机平面视频的整体透明度级别。 |
targetMaterialProperty | 在 VideoPlayer.renderMode 设置为 Video.VideoTarget.MaterialOverride 时被设为目标的材质纹理属性。 |
targetMaterialRenderer | 在 VideoPlayer.renderMode 设置为 Video.VideoTarget.MaterialOverride 时被设为目标的 Renderer |
targetTexture | 当 VideoPlayer.renderMode 设置为 Video.VideoTarget.RenderTexture 时,要在其中绘制资源的 RenderTexture。 |
texture | 放置视频内容的内部纹理。 |
time | VideoPlayer 当前时间(以秒为单位)。 |
timeReference | VideoPlayer 对其进行观测以发现和纠正偏差的时钟。 |
timeSource | [尚未实现] VideoPlayer 用于派生其当前时间的源。 |
url | VideoPlayer 将从中读取内容的文件或 HTTP URL。 |
waitForFirstFrame | 确定当 VideoPlayer.playOnAwake 启用时,VideoPlayer 是否会在开始播放之前等待第一帧加载到纹理中。 |
EnableAudioTrack | 启用/禁用音频轨道解码。仅在 VideoPlayer 当前未播放时有效。 |
GetAudioChannelCount | 指定音频轨道中的音频声道数。 |
GetAudioLanguageCode | 返回指定轨道的语言代码(如果有)。 |
GetDirectAudioMute | 获取指定轨道的直接输出音频静音状态。 |
GetDirectAudioVolume | 返回指定轨道的直接输出音量。 |
GetTargetAudioSource | 获取当 VideoPlayer.audioOutputMode 设置为 VideoAudioOutputMode.AudioSource 时将接收指定轨道的音频样本的 AudioSource。 |
IsAudioTrackEnabled | 返回是否启用了对指定音频轨道的解码。请参阅 VideoPlayer.EnableAudioTrack 以了解它与静音的区别。 |
Pause | 暂停播放并保持当前时间不变。 |
Play | 开始播放。 |
Prepare | 启动播放引擎准备。 |
SetDirectAudioMute | 设置指定轨道的直接输出音频静音状态。 |
SetDirectAudioVolume | 设置指定轨道的直接输出音频音量。 |
SetTargetAudioSource | 设置当使用 VideoPlayer.audioOutputMode 选择此音频目标时将接收指定轨道的音频样本的 AudioSource。 |
StepForward | 立即将当前时间向前推进一帧。 |
Stop | 暂停播放并将当前时间设为 0。 |
clockResyncOccurred | 在 VideoPlayer 的时钟同步回其 VideoTimeReference 时调用。 |
errorReceived | 通过此回调报告 HTTP 连接问题等错误。 |
frameDropped | [尚未实现] 当视频解码器在播放期间没有按照时间源生成帧时调用。 |
frameReady | 当新帧准备就绪时调用。 |
loopPointReached | 当 VideoPlayer 到达播放内容的结尾时调用。 |
prepareCompleted | 当 VideoPlayer 的准备工作完成后调用。 |
seekCompleted | 在搜寻操作完成后调用。 |
started | 在调用 Play 后立即调用。 |
ErrorEventHandler | 包含错误消息的 VideoPlayer 事件的委托类型。 |
EventHandler | VideoPlayer 发出的所有无参数事件的委托类型。 |
FrameReadyEventHandler | 带有帧编号的 VideoPlayer 事件的委托类型。 |
TimeEventHandler | 带有时间位置的 VideoPlayer 事件的委托类型。 |
enabled | 启用的 Behaviour 可更新,禁用的 Behaviour 不可更新。 |
isActiveAndEnabled | 已调用启用的 Behaviour。 |
gameObject | 此组件附加到的游戏对象。始终将组件附加到游戏对象。 |
tag | 此游戏对象的标签。 |
transform | 附加到此 GameObject 的 Transform。 |
hideFlags | 该对象应该隐藏、随场景一起保存还是由用户修改? |
name | 对象的名称。 |
BroadcastMessage | 调用此游戏对象或其任何子项中的每个 MonoBehaviour 上名为 methodName 的方法。 |
CompareTag | 此游戏对象是否使用 tag 进行了标记? |
GetComponent | 如果游戏对象附加了类型为 type 的组件,则将其返回,否则返回 null。 |
GetComponentInChildren | 使用深度首次搜索返回 GameObject 或其任何子项中类型为 type 的组件。 |
GetComponentInParent | 返回 GameObject 或其任何父项中类型为 type 的组件。 |
GetComponents | 返回 GameObject 中类型为 type 的所有组件。 |
GetComponentsInChildren | 返回 GameObject 或其任何子项中类型为 type 的所有组件。 |
GetComponentsInParent | 返回 GameObject 或其任何父项中类型为 type 的所有组件。 |
SendMessage | 调用此游戏对象中的每个 MonoBehaviour 上名为 methodName 的方法。 |
SendMessageUpwards | 调用此游戏对象中的每个 MonoBehaviour 上或此行为的每个父级上名为 methodName 的方法。 |
GetInstanceID | 返回对象的实例 ID。 |
ToString | 返回 GameObject 的名称。 |
Destroy | 删除 GameObject、组件或资源。 |
DestroyImmediate | 立即销毁对象 /obj/。强烈建议您改用 Destroy。 |
DontDestroyOnLoad | 在加载新的 Scene 时,请勿销毁 Object。 |
FindObjectOfType | 返回第一个类型为 type 的已加载的激活对象。 |
FindObjectsOfType | 返回所有类型为 type 的已加载的激活对象的列表。 |
Instantiate | 克隆 original 对象并返回克隆对象。 |
bool | 该对象是否存在? |
operator != | 比较两个对象是否引用不同的对象。 |
operator == | 比较两个对象引用,判断它们是否引用同一个对象。 |