UnityGame/Library/PackageCache/com.unity.timeline/Samples~/Customization/Video/VideoPlayableAsset.cs
2024-10-27 10:53:47 +03:00

132 lines
5.0 KiB
C#

using System;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
using UnityEngine.Video;
namespace Timeline.Samples
{
// Editor representation of a Clip to play video in Timeline.
[Serializable]
public class VideoPlayableAsset : PlayableAsset, ITimelineClipAsset
{
public enum RenderMode
{
CameraFarPlane,
CameraNearPlane
};
[Tooltip("The video clip to play.")]
public VideoClip videoClip;
[Tooltip("Mutes the audio from the video")]
public bool mute;
[Tooltip("Loops the video.")]
public bool loop = true;
[Tooltip("The amount of time before the video begins to start preloading the video stream.")]
public double preloadTime = 0.3;
[Tooltip("The aspect ratio of the video to playback.")]
public VideoAspectRatio aspectRatio = VideoAspectRatio.FitHorizontally;
[Tooltip("Where the video content will be drawn.")]
public RenderMode renderMode = RenderMode.CameraFarPlane;
[Tooltip("Specifies which camera to render to. If unassigned, the main camera will be used.")]
public ExposedReference<Camera> targetCamera;
[Tooltip("Specifies an optional audio source to output to.")]
public ExposedReference<AudioSource> audioSource;
// These are set by the track prior to CreatePlayable being called and are used by the VideoSchedulePlayableBehaviour
// to schedule preloading of the video clip
public double clipInTime { get; set; }
public double startTime { get; set; }
// Creates the playable that represents the instance that plays this clip.
// Here a hidden VideoPlayer is being created for the PlayableBehaviour to use
// to control playback. The PlayableBehaviour is responsible for deleting the player.
public override Playable CreatePlayable(PlayableGraph graph, GameObject go)
{
Camera camera = targetCamera.Resolve(graph.GetResolver());
if (camera == null)
camera = Camera.main;
// If we are unable to create a player, return a playable with no behaviour attached.
VideoPlayer player = CreateVideoPlayer(camera, audioSource.Resolve(graph.GetResolver()));
if (player == null)
return Playable.Create(graph);
ScriptPlayable<VideoPlayableBehaviour> playable =
ScriptPlayable<VideoPlayableBehaviour>.Create(graph);
VideoPlayableBehaviour playableBehaviour = playable.GetBehaviour();
playableBehaviour.videoPlayer = player;
playableBehaviour.preloadTime = preloadTime;
playableBehaviour.clipInTime = clipInTime;
playableBehaviour.startTime = startTime;
return playable;
}
// The playable assets duration is used to specify the initial or default duration of the clip in Timeline.
public override double duration
{
get
{
if (videoClip == null)
return base.duration;
return videoClip.length;
}
}
// Implementation of ITimelineClipAsset. This specifies the capabilities of this timeline clip inside the editor.
// For video clips, we are using built-in support for clip-in, speed, blending and looping.
public ClipCaps clipCaps
{
get
{
var caps = ClipCaps.Blending | ClipCaps.ClipIn | ClipCaps.SpeedMultiplier;
if (loop)
caps |= ClipCaps.Looping;
return caps;
}
}
VideoPlayer CreateVideoPlayer(Camera camera, AudioSource targetAudioSource)
{
if (videoClip == null)
return null;
GameObject gameObject = new GameObject(videoClip.name) { hideFlags = HideFlags.HideAndDontSave };
VideoPlayer videoPlayer = gameObject.AddComponent<VideoPlayer>();
videoPlayer.playOnAwake = false;
videoPlayer.source = VideoSource.VideoClip;
videoPlayer.clip = videoClip;
videoPlayer.waitForFirstFrame = false;
videoPlayer.skipOnDrop = true;
videoPlayer.targetCamera = camera;
videoPlayer.renderMode = renderMode == RenderMode.CameraFarPlane ? VideoRenderMode.CameraFarPlane : VideoRenderMode.CameraNearPlane;
videoPlayer.aspectRatio = aspectRatio;
videoPlayer.isLooping = loop;
videoPlayer.audioOutputMode = VideoAudioOutputMode.Direct;
if (mute)
{
videoPlayer.audioOutputMode = VideoAudioOutputMode.None;
}
else if (targetAudioSource != null)
{
videoPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource;
for (ushort i = 0; i < videoPlayer.clip.audioTrackCount; ++i)
videoPlayer.SetTargetAudioSource(i, targetAudioSource);
}
return videoPlayer;
}
}
}