杨栋梁
2 years ago
463 changed files with 108241 additions and 94 deletions
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 890f5ca9e9d84954c8d5da6c669e3316 |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: fcccc3f00c645488881030aed989c9d4 |
||||
folderAsset: yes |
||||
timeCreated: 1505748953 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,53 @@
|
||||
#if UNITY_IOS |
||||
using UnityEngine; |
||||
using System.Collections; |
||||
using UnityEditor.Callbacks; |
||||
using UnityEditor; |
||||
using System.Diagnostics; |
||||
using System.IO; |
||||
using UnityEditor.iOS.Xcode; |
||||
using System.Linq; |
||||
|
||||
public class IOSPostBuild |
||||
{ |
||||
[PostProcessBuild(1000)] |
||||
public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) |
||||
{ |
||||
PostProcessBuild(pathToBuiltProject); |
||||
} |
||||
|
||||
private static void PostProcessBuild(string path) |
||||
{ |
||||
#region pbxproj |
||||
string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj"; |
||||
|
||||
// PBXProject class represents a project build settings file, |
||||
// here is how to read that in. |
||||
PBXProject proj = new PBXProject(); |
||||
proj.ReadFromFile(projPath); |
||||
|
||||
// This is the Xcode target in the generated project |
||||
string target = proj.TargetGuidByName("Unity-iPhone"); |
||||
|
||||
// Write PBXProject object back to the file |
||||
//proj.AddBuildProperty(target, "ENABLE_BITCODE", "NO"); |
||||
|
||||
proj.AddFrameworkToProject(target, "VideoToolbox.framework", false); |
||||
proj.AddFrameworkToProject(target, "libz.tbd", false); |
||||
proj.AddFrameworkToProject(target, "libbz2.tbd", false); |
||||
proj.AddFrameworkToProject(target, "libiconv.tbd", false); |
||||
|
||||
proj.WriteToFile(projPath); |
||||
#endregion |
||||
|
||||
#region info plist |
||||
string plistPath = path + "/Info.plist"; |
||||
|
||||
PlistDocument plist = new PlistDocument(); |
||||
plist.ReadFromFile(plistPath); |
||||
plist.root.SetString("NSMicrophoneUsageDescription", "User can record himself and video"); |
||||
plist.WriteToFile(plistPath); |
||||
#endregion |
||||
} |
||||
} |
||||
#endif |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 359eb934d7023405cbeaa85319fb5366 |
||||
timeCreated: 1505748977 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,28 @@
|
||||
#if UNITY_STANDALONE_OSX |
||||
using UnityEngine; |
||||
using UnityEditor; |
||||
using UnityEditor.Callbacks; |
||||
using System.IO; |
||||
|
||||
public class WinPostBuild |
||||
{ |
||||
[PostProcessBuild(1000)] |
||||
public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) |
||||
{ |
||||
PostProcessBuild(pathToBuiltProject); |
||||
} |
||||
|
||||
static void PostProcessBuild(string path) |
||||
{ |
||||
string binarySource = |
||||
Path.Combine( |
||||
Application.dataPath, |
||||
FFmpeg.StandaloneProxy.EDITOR_BINARY_PATH); |
||||
|
||||
string buildFolder = Path.GetDirectoryName(path); |
||||
string binaryDestination = Path.Combine(buildFolder, "ffmpeg"); |
||||
|
||||
File.Copy(binarySource, binaryDestination, true); |
||||
} |
||||
} |
||||
#endif |
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2 |
||||
guid: e87405822af4744829bc4f060b819f5d |
||||
timeCreated: 1516470099 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,29 @@
|
||||
#if UNITY_STANDALONE_WIN |
||||
using UnityEngine; |
||||
using UnityEditor; |
||||
using UnityEditor.Callbacks; |
||||
using System.IO; |
||||
|
||||
public class WinPostBuild |
||||
{ |
||||
[PostProcessBuild(1000)] |
||||
public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) |
||||
{ |
||||
PostProcessBuild(pathToBuiltProject); |
||||
} |
||||
|
||||
private static void PostProcessBuild(string path) |
||||
{ |
||||
string binarySource = |
||||
Path.Combine( |
||||
Application.dataPath, |
||||
FFmpeg.StandaloneProxy.EDITOR_BINARY_PATH); |
||||
|
||||
string extension = Path.GetExtension(path); |
||||
string dataFolder = path.Replace(extension, "_Data"); |
||||
string binaryDestination = Path.Combine(dataFolder, "ffmpeg"); |
||||
|
||||
File.Copy(binarySource, binaryDestination, true); |
||||
} |
||||
} |
||||
#endif |
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2 |
||||
guid: a32532414c64983438a74ecdec7ebacc |
||||
timeCreated: 1516464104 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,77 @@
|
||||
%YAML 1.1 |
||||
%TAG !u! tag:unity3d.com,2011: |
||||
--- !u!1001 &100100000 |
||||
Prefab: |
||||
m_ObjectHideFlags: 1 |
||||
serializedVersion: 2 |
||||
m_Modification: |
||||
m_TransformParent: {fileID: 0} |
||||
m_Modifications: [] |
||||
m_RemovedComponents: [] |
||||
m_ParentPrefab: {fileID: 0} |
||||
m_RootGameObject: {fileID: 1329759316349834} |
||||
m_IsPrefabParent: 1 |
||||
--- !u!1 &1329759316349834 |
||||
GameObject: |
||||
m_ObjectHideFlags: 0 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
serializedVersion: 5 |
||||
m_Component: |
||||
- component: {fileID: 4519023348907108} |
||||
- component: {fileID: 114656708596434632} |
||||
- component: {fileID: 114842069494805180} |
||||
- component: {fileID: 114385150842497076} |
||||
m_Layer: 0 |
||||
m_Name: FFmpeg |
||||
m_TagString: Untagged |
||||
m_Icon: {fileID: 0} |
||||
m_NavMeshLayer: 0 |
||||
m_StaticEditorFlags: 0 |
||||
m_IsActive: 1 |
||||
--- !u!4 &4519023348907108 |
||||
Transform: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1329759316349834} |
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} |
||||
m_LocalPosition: {x: 0, y: 0, z: 0} |
||||
m_LocalScale: {x: 1, y: 1, z: 1} |
||||
m_Children: [] |
||||
m_Father: {fileID: 0} |
||||
m_RootOrder: 0 |
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
||||
--- !u!114 &114385150842497076 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1329759316349834} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 11500000, guid: 2db24719e44a44f05a3acbcfc039d7a3, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
--- !u!114 &114656708596434632 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1329759316349834} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 11500000, guid: 414d4f09fac14ca4dadf24c3e2f296ff, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
--- !u!114 &114842069494805180 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1329759316349834} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 11500000, guid: 1f3b5e6148f704c65aca6d4d300ec2dc, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 62e3898569660b0479c5f3232ee87134 |
||||
timeCreated: 1494108781 |
||||
licenseType: Store |
||||
NativeFormatImporter: |
||||
mainObjectFileID: 100100000 |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 798827c46ffc96742b0880c8d98f2522 |
||||
folderAsset: yes |
||||
timeCreated: 1494106279 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 0d4de293ce7a70845944564e8e9e3958 |
||||
folderAsset: yes |
||||
timeCreated: 1494105826 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,399 @@
|
||||
using UnityEngine; |
||||
using FFmpeg; |
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using System.Text; |
||||
|
||||
/// <summary> |
||||
/// Entry point for FFmpeg |
||||
/// </summary> |
||||
public static class FFmpegCommands |
||||
{ |
||||
//Do not call this |
||||
static FFmpegWrapper w; |
||||
//Call this ------------| |
||||
// | |
||||
// \|/ |
||||
static FFmpegWrapper Wrapper |
||||
{ |
||||
get |
||||
{ |
||||
if (w == null) |
||||
{ |
||||
w = MonoBehaviour.FindObjectOfType<FFmpegWrapper>(); |
||||
if (w == null) |
||||
Debug.LogException(new Exception("Place a FFmpeg.prefab in the scene")); |
||||
} |
||||
return w; |
||||
} |
||||
} |
||||
//Data (instructions) |
||||
public const char SEPARATOR = ' '; |
||||
public const char QUOTE = '\''; |
||||
public const char DOUBLE_QUOTE = '\"'; |
||||
public const string VERSION_INSTRUCTION = "-version"; |
||||
public const string REWRITE_INSTRUCTION = "-y"; |
||||
public const string INPUT_INSTRUCTION = "-i"; |
||||
public const string INDEX_PREFIX_INSTRUCTION = "%"; |
||||
public const string INDEX_SUFIX_INSTRUCTION = "d"; |
||||
public const string RESIZE_INSTRUCTION = "-r"; |
||||
public const string SS_INSTRUCTION = "-ss"; |
||||
public const string CODEC_INSTRUCTION = "-codec"; |
||||
public const string C_CODEC_INSTRUCTION = "-c"; |
||||
public const string COPY_INSTRUCTION = "copy"; |
||||
public const string TIME_INSTRUCTION = "-t"; |
||||
public const string CODEC_VIDEO_INSTRUCTION = "-c:v"; |
||||
public const string CODEC_AUDIO_INSTRUCTION = "-c:a"; |
||||
public const string LIB_X264_INSTRUCTION = "libx264"; |
||||
public const string CONSTANT_RATE_FACTOR_INSTRUCTION = "-crf"; |
||||
public const string FILE_FORMAT_INPUT_INSTRUCTION = "-f"; |
||||
public const string CONCAT_INSTRUCTION = "concat"; |
||||
public const string SAFE_INSTRUCTION = "-safe"; |
||||
public const string ZERO_INSTRUCTION = "0"; |
||||
public const string FILTER_COMPLEX_INSTRUCTION = "-filter_complex"; |
||||
public const string MAP_INSTRUCTION = "-map"; |
||||
public const string PRESET_INSTRUCTION = "-preset"; |
||||
public const string VIDEO_INSTRUCTION = "[v]"; |
||||
public const string AUDIO_INSTRUCTION = "[a]"; |
||||
public const string ULTRASAFE_INSTRUCTION = "ultrafast"; |
||||
public const string VIDEO_FORMAT = "[{0}:v:0] "; |
||||
public const string AUDIO_FORMAT = "[{0}:a:0] "; |
||||
public const string CONCAT_FORMAT = "{0}=n={1}:v=1:a=1"; |
||||
public const string FIRST_INPUT_VIDEO_CHANNEL = "0:v"; |
||||
public const string SECOND_INPUT_AUDIO_CHANNEL = "1:a"; |
||||
public const string SHORTEST_INSTRUCTION = "-shortest"; |
||||
public const string PIXEL_FORMAT = "-pix_fmt"; |
||||
public const string YUV_420P = "yuv420p"; |
||||
|
||||
//------------------------------ |
||||
|
||||
public static void GetVersion() |
||||
{ |
||||
Wrapper.Execute(new string[] { VERSION_INSTRUCTION }); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public static void Convert(BaseData config) |
||||
{ |
||||
//-y -i .../input.mp4 .../output.mp3 |
||||
string[] command = |
||||
{ |
||||
REWRITE_INSTRUCTION, |
||||
INPUT_INSTRUCTION, |
||||
config.inputPath, |
||||
config.outputPath |
||||
}; |
||||
|
||||
DebugCommand(command); |
||||
|
||||
Wrapper.Execute(command); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public static void Trim(TrimData config) |
||||
{ |
||||
//-y -i .../input.mp4 -ss 00:00:50.0 -codec copy -t 20 .../output.mp4 |
||||
string[] command = |
||||
{ |
||||
REWRITE_INSTRUCTION, |
||||
INPUT_INSTRUCTION, |
||||
config.inputPath, |
||||
SS_INSTRUCTION, |
||||
config.fromTime, |
||||
CODEC_INSTRUCTION, |
||||
COPY_INSTRUCTION, |
||||
TIME_INSTRUCTION, |
||||
config.durationSec.ToString(), |
||||
config.outputPath |
||||
}; |
||||
|
||||
DebugCommand(command); |
||||
|
||||
Wrapper.Execute(command); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public static void Decode(DecodeEncodeData config) |
||||
{ |
||||
//-y -i .../video.mp4 -r 30 .../image%1d.jpg .../track.mp3 |
||||
string[] command = |
||||
{ |
||||
REWRITE_INSTRUCTION, |
||||
INPUT_INSTRUCTION, |
||||
config.inputPath, |
||||
RESIZE_INSTRUCTION, |
||||
config.fps.ToString(), |
||||
config.outputPath, |
||||
config.soundPath |
||||
}; |
||||
|
||||
DebugCommand(command); |
||||
|
||||
Wrapper.Execute(command); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public static void Encode(DecodeEncodeData config) |
||||
{ |
||||
//-y -i .../image%1d.jpg -r 30 -i .../track.mp3 -pix_fmt yuv420p .../video.mp4 |
||||
string[] command = |
||||
{ |
||||
REWRITE_INSTRUCTION, |
||||
INPUT_INSTRUCTION, |
||||
config.inputPath, |
||||
RESIZE_INSTRUCTION, |
||||
config.fps.ToString(), |
||||
INPUT_INSTRUCTION, |
||||
config.soundPath, |
||||
PIXEL_FORMAT, |
||||
YUV_420P, |
||||
config.outputPath |
||||
}; |
||||
|
||||
DebugCommand(command); |
||||
|
||||
Wrapper.Execute(command); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public static void Compress(CompressionData config) |
||||
{ |
||||
//-i .../input.mp4 -c:v libx264 -crf 23 .../output.mp4 -y |
||||
string[] command = |
||||
{ |
||||
INPUT_INSTRUCTION, |
||||
config.inputPath, |
||||
CODEC_VIDEO_INSTRUCTION, |
||||
LIB_X264_INSTRUCTION, |
||||
CONSTANT_RATE_FACTOR_INSTRUCTION, |
||||
config.crf.ToString(), |
||||
config.outputPath, |
||||
REWRITE_INSTRUCTION |
||||
}; |
||||
|
||||
DebugCommand(command); |
||||
|
||||
Wrapper.Execute(command); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public static void AppendFast(AppendData config) |
||||
{ |
||||
//-f concat -safe 0 -i .../mylist.txt -c copy .../output.mp4 -y |
||||
string[] command = |
||||
{ |
||||
FILE_FORMAT_INPUT_INSTRUCTION, |
||||
CONCAT_INSTRUCTION, |
||||
SAFE_INSTRUCTION, |
||||
ZERO_INSTRUCTION, |
||||
INPUT_INSTRUCTION, |
||||
GetInputsFile(config.inputPaths), |
||||
C_CODEC_INSTRUCTION, |
||||
COPY_INSTRUCTION, |
||||
config.outputPath, |
||||
REWRITE_INSTRUCTION |
||||
}; |
||||
|
||||
DebugCommand(command); |
||||
|
||||
Wrapper.Execute(command); |
||||
} |
||||
|
||||
static string GetInputsFile(List<string> inputPaths) |
||||
{ |
||||
string inputFolder = Path.GetDirectoryName( |
||||
//Remove standalone style |
||||
inputPaths[0].Replace("\"", string.Empty)); |
||||
|
||||
StringBuilder fileBuffer = new StringBuilder(); |
||||
fileBuffer.Append("# File with input videos\n"); |
||||
foreach(string ip in inputPaths) |
||||
{ |
||||
//Relative to input folder |
||||
string inputPath = ip.Remove(0, inputFolder.Length); |
||||
//Remove standalone style |
||||
inputPath = ip.Replace("\"", string.Empty); |
||||
|
||||
fileBuffer.Append("file '" + inputPath + "'\n"); |
||||
} |
||||
|
||||
string filePath = Path.Combine(inputFolder, "AppendInputFiles.txt"); |
||||
using (FileStream fileStream = File.Create(filePath)) |
||||
{ |
||||
byte[] buffer = |
||||
new UTF8Encoding(true).GetBytes(fileBuffer.ToString()); |
||||
fileStream.Write(buffer, 0, buffer.Length); |
||||
} |
||||
#if UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN || UNITY_EDITOR |
||||
filePath = DOUBLE_QUOTE + filePath + DOUBLE_QUOTE; |
||||
#endif |
||||
Debug.Log("FilePath: " + filePath); |
||||
return filePath; |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public static void AppendFull(AppendData config) |
||||
{ |
||||
//ffmpeg - i .../input1.mp4 - i .../input2.webm \ |
||||
//-filter_complex "[0:v:0] [0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]" \ |
||||
//-map "[v]" - map "[a]" < encoding options > .../output.mkv -y |
||||
List<string> cmd = new List<string>(); |
||||
StringBuilder filter = new StringBuilder(); |
||||
#if UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN || UNITY_EDITOR |
||||
filter.Append(DOUBLE_QUOTE); |
||||
#endif |
||||
for (int i = 0; i < config.inputPaths.Count; ++i) |
||||
{ |
||||
cmd.Add(INPUT_INSTRUCTION); |
||||
cmd.Add(config.inputPaths[i]); |
||||
|
||||
filter.Append(string.Format(VIDEO_FORMAT, i)).Append(string.Format(AUDIO_FORMAT, i)); |
||||
} |
||||
|
||||
filter. |
||||
Append(string.Format(CONCAT_FORMAT, CONCAT_INSTRUCTION, config.inputPaths.Count)). |
||||
Append(SEPARATOR). |
||||
Append(VIDEO_INSTRUCTION). |
||||
Append(SEPARATOR). |
||||
Append(AUDIO_INSTRUCTION); |
||||
#if UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN || UNITY_EDITOR |
||||
filter.Append(DOUBLE_QUOTE); |
||||
#endif |
||||
|
||||
cmd.Add(FILTER_COMPLEX_INSTRUCTION); |
||||
cmd.Add(filter.ToString()); |
||||
cmd.Add(MAP_INSTRUCTION); |
||||
cmd.Add(VIDEO_INSTRUCTION); |
||||
cmd.Add(MAP_INSTRUCTION); |
||||
cmd.Add(AUDIO_INSTRUCTION); |
||||
cmd.Add(PRESET_INSTRUCTION); |
||||
cmd.Add(ULTRASAFE_INSTRUCTION); |
||||
cmd.Add(config.outputPath); |
||||
cmd.Add(REWRITE_INSTRUCTION); |
||||
|
||||
string[] command = cmd.ToArray(); |
||||
|
||||
DebugCommand(command); |
||||
|
||||
Wrapper.Execute(command); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public static void AddSoundFast(SoundData config) |
||||
{ |
||||
//aac is compatible with mp4 - no need full re-encoding. |
||||
//-y -i .../input.mp4 -i .../audio.aac -c copy -map 0:v -map 1:a -shortest .../output.mp4 |
||||
string[] command = |
||||
{ |
||||
REWRITE_INSTRUCTION, |
||||
INPUT_INSTRUCTION, |
||||
config.inputPath, |
||||
INPUT_INSTRUCTION, |
||||
config.soundPath, |
||||
C_CODEC_INSTRUCTION, |
||||
COPY_INSTRUCTION, |
||||
MAP_INSTRUCTION, |
||||
FIRST_INPUT_VIDEO_CHANNEL, |
||||
MAP_INSTRUCTION, |
||||
SECOND_INPUT_AUDIO_CHANNEL, |
||||
SHORTEST_INSTRUCTION, |
||||
config.outputPath |
||||
}; |
||||
|
||||
DebugCommand(command); |
||||
|
||||
Wrapper.Execute(command); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public static void AddSoundFull(SoundData config) |
||||
{ |
||||
//mp3 is does not compatible with mp4. Full re-encoding handles this. |
||||
//-y -i .../audio.mp3 -i .../input.mp4 .../output.mp4 |
||||
string[] command = |
||||
{ |
||||
REWRITE_INSTRUCTION, |
||||
INPUT_INSTRUCTION, |
||||
config.soundPath, |
||||
INPUT_INSTRUCTION, |
||||
config.inputPath, |
||||
config.outputPath |
||||
}; |
||||
|
||||
DebugCommand(command); |
||||
|
||||
Wrapper.Execute(command); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public static void Watermark(WatermarkData config) |
||||
{ |
||||
//-y -i .../watermark.png -i .../input.mp4 -filter_complex \ |
||||
//"[0:v]scale=iw*0.25:ih*0.25 [ovrl], [1:v][ovrl]overlay=x=(main_w-overlay_w)*0.95:y=(main_h-overlay_h)*0.05" \ |
||||
//FFmpegUnityBindDemo.mp4 |
||||
StringBuilder filter = new StringBuilder(); |
||||
#if UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN || UNITY_EDITOR |
||||
filter.Append(DOUBLE_QUOTE); |
||||
#endif |
||||
filter. |
||||
Append("[0:v]scale=iw*"). |
||||
Append(config.imageScale). |
||||
Append(":ih*"). |
||||
Append(config.imageScale). |
||||
Append(" [ovrl], [1:v][ovrl]overlay=x=(main_w-overlay_w)*"). |
||||
Append(config.xPosNormal). |
||||
Append(":y=(main_h-overlay_h)*"). |
||||
Append(config.yPosNormal); |
||||
#if UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN || UNITY_EDITOR |
||||
filter.Append(DOUBLE_QUOTE); |
||||
#endif |
||||
|
||||
string[] command = |
||||
{ |
||||
REWRITE_INSTRUCTION, |
||||
INPUT_INSTRUCTION, |
||||
config.imagePath, |
||||
INPUT_INSTRUCTION, |
||||
config.inputPath, |
||||
FILTER_COMPLEX_INSTRUCTION, |
||||
filter.ToString(), |
||||
config.outputPath |
||||
}; |
||||
|
||||
DebugCommand(command); |
||||
|
||||
Wrapper.Execute(command); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public static void DirectInput(string input) |
||||
{ |
||||
string[] command = input.Split(' '); |
||||
|
||||
DebugCommand(command); |
||||
|
||||
Wrapper.Execute(command); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
static void DebugCommand(string[] command) |
||||
{ |
||||
StringBuilder debugCommand = new StringBuilder(); |
||||
foreach (string instruction in command) |
||||
debugCommand.Append(instruction + " "); |
||||
Debug.Log(debugCommand.ToString()); |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: bf4b2c3165228674f912efe2cff60995 |
||||
timeCreated: 1494102306 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,53 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace FFmpeg |
||||
{ |
||||
[Serializable] |
||||
public class BaseData |
||||
{ |
||||
public string inputPath; |
||||
public string outputPath; |
||||
} |
||||
|
||||
[Serializable] |
||||
public class SoundData : BaseData |
||||
{ |
||||
public string soundPath; |
||||
} |
||||
|
||||
[Serializable] |
||||
public class DecodeEncodeData : SoundData |
||||
{ |
||||
public float fps; |
||||
} |
||||
|
||||
[Serializable] |
||||
public class TrimData : BaseData |
||||
{ |
||||
public string fromTime; //"00:00:01.0" - after first second |
||||
public int durationSec; |
||||
} |
||||
|
||||
[Serializable] |
||||
public class CompressionData : BaseData |
||||
{ |
||||
public int crf; |
||||
} |
||||
|
||||
[Serializable] |
||||
public class AppendData |
||||
{ |
||||
public List<string> inputPaths = new List<string>(); |
||||
public string outputPath; |
||||
} |
||||
|
||||
[Serializable] |
||||
public class WatermarkData : BaseData |
||||
{ |
||||
public string imagePath; |
||||
public float imageScale; |
||||
public float xPosNormal; |
||||
public float yPosNormal; |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 5205e809d4416734599a47b31c7abd8f |
||||
timeCreated: 1494257500 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,26 @@
|
||||
using System; |
||||
using UnityEngine; |
||||
|
||||
namespace FFmpeg |
||||
{ |
||||
interface IFFmpegHandler |
||||
{ |
||||
void OnStart(); |
||||
void OnProgress(string msg); |
||||
void OnFailure(string msg); |
||||
void OnSuccess(string msg); |
||||
void OnFinish(); |
||||
} |
||||
|
||||
|
||||
public class FFmpegHandler : IFFmpegHandler |
||||
{ |
||||
//Default implementation |
||||
//------------------------------ |
||||
public void OnStart() { Debug.Log("FFmpegHandler.Start"); } |
||||
public void OnProgress(string msg) { Debug.Log("FFmpegHandler.Progress: " + msg); } |
||||
public void OnFailure(string msg) { Debug.Log("FFmpegHandler.Failure: " + msg); } |
||||
public void OnSuccess(string msg) { Debug.Log("FFmpegHandler.Success: " + msg); } |
||||
public void OnFinish() { Debug.Log("FFmpegHandler.Finish"); } |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 7a07f550e5b7fbf4e83a0f1d6aaffd1b |
||||
timeCreated: 1494104255 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,82 @@
|
||||
using System; |
||||
using UnityEngine; |
||||
|
||||
namespace FFmpeg |
||||
{ |
||||
public static class FFmpegParser |
||||
{ |
||||
internal static IFFmpegHandler Handler { get; set; } |
||||
//Data |
||||
public const string COMMAND_CODE = "FFmpeg COMMAND: "; |
||||
public const string ERROR_CODE = "FFmpeg EXCEPTION: "; |
||||
public const string START_CODE = "onStart"; |
||||
public const string PROGRESS_CODE = "onProgress: "; |
||||
public const string FAILURE_CODE = "onFailure: "; |
||||
public const string SUCCESS_CODE = "onSuccess: "; |
||||
public const string FINISH_CODE = "onFinish"; |
||||
|
||||
//------------------------------ |
||||
|
||||
public static void Handle(string message) |
||||
{ |
||||
if(string.IsNullOrEmpty(message)) |
||||
{ |
||||
Debug.LogWarning("FFmpeg callback is null."); |
||||
return; |
||||
} |
||||
|
||||
if (IsCode(ref message, COMMAND_CODE)) |
||||
{ |
||||
if (IsCode(message, START_CODE)) |
||||
{ |
||||
Handler.OnStart(); |
||||
} |
||||
else if (IsCode(ref message, PROGRESS_CODE)) |
||||
{ |
||||
Handler.OnProgress(message); |
||||
} |
||||
else if (IsCode(ref message, FAILURE_CODE)) |
||||
{ |
||||
Handler.OnFailure(message); |
||||
} |
||||
else if (IsCode(ref message, SUCCESS_CODE)) |
||||
{ |
||||
Handler.OnSuccess(message); |
||||
} |
||||
else if (IsCode(message, FINISH_CODE)) |
||||
{ |
||||
Handler.OnFinish(); |
||||
} |
||||
} |
||||
else if(IsCode(message, ERROR_CODE)) |
||||
{ |
||||
Debug.LogError(message); |
||||
GameObject.Find("Canvas").transform.Find("RecSavePanel").GetComponent<RecSavePanel>().SetTip("保存失败"); |
||||
} |
||||
} |
||||
|
||||
static bool IsCode(ref string message, string CODE) |
||||
{ |
||||
if (string.IsNullOrEmpty(message)) |
||||
{ |
||||
Debug.LogWarning("FFmpegParser: Empty callback message."); |
||||
} |
||||
else if (message.Contains(CODE)) |
||||
{ |
||||
message = message.Remove(0, CODE.Length); |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
static bool IsCode(string message, string CODE) |
||||
{ |
||||
if (string.IsNullOrEmpty(message)) |
||||
{ |
||||
Debug.LogWarning("FFmpegParser: Empty callback message."); |
||||
return false; |
||||
} |
||||
return message.Contains(CODE); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 9952bc2f51fdc6849b6082018258f4fc |
||||
timeCreated: 1494102484 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,68 @@
|
||||
using System; |
||||
using UnityEngine; |
||||
|
||||
namespace FFmpeg |
||||
{ |
||||
/// <summary> |
||||
/// This is the Helper class to get FFmpeg operation progress. |
||||
/// </summary> |
||||
public static class FFmpegProgressParser |
||||
{ |
||||
const string FORMAT = "HH:mm:ss.ff"; |
||||
static readonly string[] durationSeparators = { "Duration: ", ", start:" }; |
||||
static readonly string[] timeSeparators = { " time=", " bitrate=" }; |
||||
static int lastDurationTokensLength; |
||||
|
||||
//PUBLIC INTERFACE |
||||
//------------------------------ |
||||
|
||||
public static void Parse(string log, ref float durationMiniSec, ref float progress) |
||||
{ |
||||
string[] durationTokens = log.Split(durationSeparators, StringSplitOptions.RemoveEmptyEntries); |
||||
if(durationTokens.Length != lastDurationTokensLength) |
||||
{ |
||||
UpdateDuration(durationTokens, ref durationMiniSec); |
||||
lastDurationTokensLength = durationTokens.Length; |
||||
} |
||||
else if(durationMiniSec > 0) //When Duration is obtained |
||||
{ |
||||
string timeToken = GetTimeToken(log, timeSeparators); |
||||
if(timeToken != null) |
||||
{ |
||||
progress = GetMiliSec(timeToken) / durationMiniSec; |
||||
} |
||||
} |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
static void UpdateDuration(string[] tokens, ref float durationMiniSec) |
||||
{ |
||||
durationMiniSec = 0; |
||||
for (int t = 0; t < tokens.Length; ++t) |
||||
{ |
||||
durationMiniSec += GetMiliSec(tokens[t]); |
||||
} |
||||
} |
||||
|
||||
static string GetTimeToken(string log, string[] separators) |
||||
{ |
||||
string[] tokens = log.Split(separators, StringSplitOptions.RemoveEmptyEntries); |
||||
if(tokens.Length > 2) |
||||
{ |
||||
return tokens[tokens.Length - 2]; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
static float GetMiliSec(string token) |
||||
{ |
||||
DateTime time; |
||||
if (DateTime.TryParseExact(token, FORMAT, null, System.Globalization.DateTimeStyles.None, out time)) |
||||
{ |
||||
return (float)time.TimeOfDay.TotalMilliseconds; |
||||
} |
||||
return 0; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: e1c3db01c7a2e40b090e76640a57ec3f |
||||
timeCreated: 1507185808 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: d3a31090f40b1459385ce1c12ac90828 |
||||
folderAsset: yes |
||||
timeCreated: 1505946622 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,221 @@
|
||||
#define ENABLE_UPDATE_FUNCTION_CALLBACK |
||||
#define ENABLE_LATEUPDATE_FUNCTION_CALLBACK |
||||
#define ENABLE_FIXEDUPDATE_FUNCTION_CALLBACK |
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using UnityEngine; |
||||
using System.Collections.Generic; |
||||
|
||||
|
||||
public class UnityThread : MonoBehaviour |
||||
{ |
||||
//our (singleton) instance |
||||
private static UnityThread instance = null; |
||||
|
||||
|
||||
////////////////////////////////////////////////UPDATE IMPL//////////////////////////////////////////////////////// |
||||
//Holds actions received from another Thread. Will be coped to actionCopiedQueueUpdateFunc then executed from there |
||||
private static List<System.Action> actionQueuesUpdateFunc = new List<Action>(); |
||||
|
||||
//holds Actions copied from actionQueuesUpdateFunc to be executed |
||||
List<System.Action> actionCopiedQueueUpdateFunc = new List<System.Action>(); |
||||
|
||||
// Used to know if whe have new Action function to execute. This prevents the use of the lock keyword every frame |
||||
private volatile static bool noActionQueueToExecuteUpdateFunc = true; |
||||
|
||||
|
||||
////////////////////////////////////////////////LATEUPDATE IMPL//////////////////////////////////////////////////////// |
||||
//Holds actions received from another Thread. Will be coped to actionCopiedQueueLateUpdateFunc then executed from there |
||||
private static List<System.Action> actionQueuesLateUpdateFunc = new List<Action>(); |
||||
|
||||
//holds Actions copied from actionQueuesLateUpdateFunc to be executed |
||||
List<System.Action> actionCopiedQueueLateUpdateFunc = new List<System.Action>(); |
||||
|
||||
// Used to know if whe have new Action function to execute. This prevents the use of the lock keyword every frame |
||||
private volatile static bool noActionQueueToExecuteLateUpdateFunc = true; |
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////FIXEDUPDATE IMPL//////////////////////////////////////////////////////// |
||||
//Holds actions received from another Thread. Will be coped to actionCopiedQueueFixedUpdateFunc then executed from there |
||||
private static List<System.Action> actionQueuesFixedUpdateFunc = new List<Action>(); |
||||
|
||||
//holds Actions copied from actionQueuesFixedUpdateFunc to be executed |
||||
List<System.Action> actionCopiedQueueFixedUpdateFunc = new List<System.Action>(); |
||||
|
||||
// Used to know if whe have new Action function to execute. This prevents the use of the lock keyword every frame |
||||
private volatile static bool noActionQueueToExecuteFixedUpdateFunc = true; |
||||
|
||||
|
||||
//Used to initialize UnityThread. Call once before any function here |
||||
public static void initUnityThread(bool visible = false) |
||||
{ |
||||
if (instance != null) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
if (Application.isPlaying) |
||||
{ |
||||
// add an invisible game object to the scene |
||||
GameObject obj = new GameObject("MainThreadExecuter"); |
||||
if (!visible) |
||||
{ |
||||
obj.hideFlags = HideFlags.HideAndDontSave; |
||||
} |
||||
|
||||
DontDestroyOnLoad(obj); |
||||
instance = obj.AddComponent<UnityThread>(); |
||||
} |
||||
} |
||||
|
||||
public void Awake() |
||||
{ |
||||
DontDestroyOnLoad(gameObject); |
||||
} |
||||
|
||||
//////////////////////////////////////////////COROUTINE IMPL////////////////////////////////////////////////////// |
||||
#if (ENABLE_UPDATE_FUNCTION_CALLBACK) |
||||
public static void executeCoroutine(IEnumerator action) |
||||
{ |
||||
if (instance != null) |
||||
{ |
||||
executeInUpdate(() => instance.StartCoroutine(action)); |
||||
} |
||||
} |
||||
|
||||
////////////////////////////////////////////UPDATE IMPL//////////////////////////////////////////////////// |
||||
public static void executeInUpdate(System.Action action) |
||||
{ |
||||
if (action == null) |
||||
{ |
||||
throw new ArgumentNullException("action"); |
||||
} |
||||
|
||||
lock (actionQueuesUpdateFunc) |
||||
{ |
||||
actionQueuesUpdateFunc.Add(action); |
||||
noActionQueueToExecuteUpdateFunc = false; |
||||
} |
||||
} |
||||
|
||||
public void Update() |
||||
{ |
||||
if (noActionQueueToExecuteUpdateFunc) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
//Clear the old actions from the actionCopiedQueueUpdateFunc queue |
||||
actionCopiedQueueUpdateFunc.Clear(); |
||||
lock (actionQueuesUpdateFunc) |
||||
{ |
||||
//Copy actionQueuesUpdateFunc to the actionCopiedQueueUpdateFunc variable |
||||
actionCopiedQueueUpdateFunc.AddRange(actionQueuesUpdateFunc); |
||||
//Now clear the actionQueuesUpdateFunc since we've done copying it |
||||
actionQueuesUpdateFunc.Clear(); |
||||
noActionQueueToExecuteUpdateFunc = true; |
||||
} |
||||
|
||||
// Loop and execute the functions from the actionCopiedQueueUpdateFunc |
||||
for (int i = 0; i < actionCopiedQueueUpdateFunc.Count; i++) |
||||
{ |
||||
actionCopiedQueueUpdateFunc[i].Invoke(); |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
////////////////////////////////////////////LATEUPDATE IMPL//////////////////////////////////////////////////// |
||||
#if (ENABLE_LATEUPDATE_FUNCTION_CALLBACK) |
||||
public static void executeInLateUpdate(System.Action action) |
||||
{ |
||||
if (action == null) |
||||
{ |
||||
throw new ArgumentNullException("action"); |
||||
} |
||||
|
||||
lock (actionQueuesLateUpdateFunc) |
||||
{ |
||||
actionQueuesLateUpdateFunc.Add(action); |
||||
noActionQueueToExecuteLateUpdateFunc = false; |
||||
} |
||||
} |
||||
|
||||
|
||||
public void LateUpdate() |
||||
{ |
||||
if (noActionQueueToExecuteLateUpdateFunc) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
//Clear the old actions from the actionCopiedQueueLateUpdateFunc queue |
||||
actionCopiedQueueLateUpdateFunc.Clear(); |
||||
lock (actionQueuesLateUpdateFunc) |
||||
{ |
||||
//Copy actionQueuesLateUpdateFunc to the actionCopiedQueueLateUpdateFunc variable |
||||
actionCopiedQueueLateUpdateFunc.AddRange(actionQueuesLateUpdateFunc); |
||||
//Now clear the actionQueuesLateUpdateFunc since we've done copying it |
||||
actionQueuesLateUpdateFunc.Clear(); |
||||
noActionQueueToExecuteLateUpdateFunc = true; |
||||
} |
||||
|
||||
// Loop and execute the functions from the actionCopiedQueueLateUpdateFunc |
||||
for (int i = 0; i < actionCopiedQueueLateUpdateFunc.Count; i++) |
||||
{ |
||||
actionCopiedQueueLateUpdateFunc[i].Invoke(); |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
////////////////////////////////////////////FIXEDUPDATE IMPL////////////////////////////////////////////////// |
||||
#if (ENABLE_FIXEDUPDATE_FUNCTION_CALLBACK) |
||||
public static void executeInFixedUpdate(System.Action action) |
||||
{ |
||||
if (action == null) |
||||
{ |
||||
throw new ArgumentNullException("action"); |
||||
} |
||||
|
||||
lock (actionQueuesFixedUpdateFunc) |
||||
{ |
||||
actionQueuesFixedUpdateFunc.Add(action); |
||||
noActionQueueToExecuteFixedUpdateFunc = false; |
||||
} |
||||
} |
||||
|
||||
public void FixedUpdate() |
||||
{ |
||||
if (noActionQueueToExecuteFixedUpdateFunc) |
||||
{ |
||||
return; |
||||
} |
||||
|
||||
//Clear the old actions from the actionCopiedQueueFixedUpdateFunc queue |
||||
actionCopiedQueueFixedUpdateFunc.Clear(); |
||||
lock (actionQueuesFixedUpdateFunc) |
||||
{ |
||||
//Copy actionQueuesFixedUpdateFunc to the actionCopiedQueueFixedUpdateFunc variable |
||||
actionCopiedQueueFixedUpdateFunc.AddRange(actionQueuesFixedUpdateFunc); |
||||
//Now clear the actionQueuesFixedUpdateFunc since we've done copying it |
||||
actionQueuesFixedUpdateFunc.Clear(); |
||||
noActionQueueToExecuteFixedUpdateFunc = true; |
||||
} |
||||
|
||||
// Loop and execute the functions from the actionCopiedQueueFixedUpdateFunc |
||||
for (int i = 0; i < actionCopiedQueueFixedUpdateFunc.Count; i++) |
||||
{ |
||||
actionCopiedQueueFixedUpdateFunc[i].Invoke(); |
||||
} |
||||
} |
||||
#endif |
||||
|
||||
public void OnDisable() |
||||
{ |
||||
if (instance == this) |
||||
{ |
||||
instance = null; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 1f3b5e6148f704c65aca6d4d300ec2dc |
||||
timeCreated: 1505946638 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,96 @@
|
||||
using UnityEngine; |
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
|
||||
#if UNITY_IOS && !UNITY_EDITOR |
||||
using System.Runtime.InteropServices; |
||||
#endif |
||||
|
||||
namespace FFmpeg |
||||
{ |
||||
public class FFmpegWrapper : MonoBehaviour |
||||
{ |
||||
#if UNITY_IOS && !UNITY_EDITOR |
||||
|
||||
[System.Security.SuppressUnmanagedCodeSecurity()] |
||||
//void* execute(char** argv, int argc, void (* callback)(const char*)) |
||||
[DllImport("__Internal")] |
||||
static extern void execute(string[] argv, int argc, IOSCallback callback); |
||||
|
||||
delegate void IOSCallback(string msg); |
||||
[AOT.MonoPInvokeCallback(typeof(IOSCallback))] |
||||
static void IOSCallbacFunc(string message) |
||||
{ |
||||
callbackMSGs.Enqueue(message); |
||||
} |
||||
|
||||
#elif UNITY_ANDROID && !UNITY_EDITOR |
||||
AndroidJavaClass unityClass; |
||||
AndroidJavaObject pluginClass; |
||||
|
||||
//------------------------------ |
||||
|
||||
class AndroidCallback : AndroidJavaProxy |
||||
{ |
||||
public AndroidCallback() : base("com.botvinev.max.unityplugin.CallbackNotifier") { } |
||||
void onEnd(string message) |
||||
{ |
||||
callbackMSGs.Enqueue(message); |
||||
} |
||||
} |
||||
#elif UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN || UNITY_EDITOR |
||||
static void StandaloneCallback(string message) |
||||
{ |
||||
callbackMSGs.Enqueue(message); |
||||
} |
||||
#endif |
||||
static Queue<string> callbackMSGs = new Queue<string>(); |
||||
|
||||
//------------------------------ |
||||
|
||||
void Start() |
||||
{ |
||||
#if UNITY_IOS && !UNITY_EDITOR |
||||
//IOS implementation doesn't need initialization |
||||
#elif UNITY_ANDROID && !UNITY_EDITOR |
||||
unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); |
||||
pluginClass = new AndroidJavaObject("com.botvinev.max.unityplugin.VideoProcessing"); |
||||
pluginClass.Call( |
||||
"Begin", |
||||
unityClass.GetStatic<AndroidJavaObject>("currentActivity"), //Context |
||||
new AndroidCallback()); |
||||
#elif UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN || UNITY_EDITOR |
||||
StandaloneProxy.Begin(StandaloneCallback); |
||||
#else |
||||
Debug.LogWarning("FFmpeg is not implemented for " + Application.platform); |
||||
#endif |
||||
} |
||||
|
||||
internal void Execute(string[] cmd) |
||||
{ |
||||
#if UNITY_IOS && !UNITY_EDITOR |
||||
execute(cmd, cmd.Length, IOSCallbacFunc); |
||||
#elif UNITY_ANDROID && !UNITY_EDITOR |
||||
pluginClass.Call( |
||||
"Process", |
||||
unityClass.GetStatic<AndroidJavaObject>("currentActivity"), //Context |
||||
cmd, |
||||
new AndroidCallback()); |
||||
#elif UNITY_STANDALONE_OSX || UNITY_STANDALONE_WIN || UNITY_EDITOR |
||||
StandaloneProxy.Execute(string.Join(" ", cmd)); |
||||
#else |
||||
Debug.LogWarning("FFmpeg is not implemented for " + Application.platform); |
||||
#endif |
||||
} |
||||
|
||||
void Update() |
||||
{ |
||||
if (callbackMSGs.Count > 0) |
||||
{ |
||||
FFmpegParser.Handle(callbackMSGs.Dequeue()); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 414d4f09fac14ca4dadf24c3e2f296ff |
||||
timeCreated: 1493981673 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 0ef485d93e4530c42b4b8577018f1aa7 |
||||
folderAsset: yes |
||||
timeCreated: 1494248975 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,137 @@
|
||||
using UnityEngine; |
||||
|
||||
namespace FFmpeg.Demo |
||||
{ |
||||
public class FFmpegDemo : MonoBehaviour, IFFmpegHandler |
||||
{ |
||||
public ProgressView progressView; |
||||
public ConvertView convertView; |
||||
public TrimView trimView; |
||||
public DecodeView decodeView; |
||||
public EncodeView encodeView; |
||||
public CompressView compressView; |
||||
public AppendView appendView; |
||||
public AddSoundView addSoundView; |
||||
public WatermarkView watermarkView; |
||||
|
||||
FFmpegHandler defaultHandler = new FFmpegHandler(); |
||||
|
||||
//------------------------------ |
||||
|
||||
void Awake() |
||||
{ |
||||
FFmpegParser.Handler = this; |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnVersion() |
||||
{ |
||||
FFmpegCommands.GetVersion(); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnConvert() |
||||
{ |
||||
convertView.Open(); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnTrim() |
||||
{ |
||||
trimView.Open(); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnDecode() |
||||
{ |
||||
decodeView.Open(); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnEncode() |
||||
{ |
||||
encodeView.Open(); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnCompress() |
||||
{ |
||||
compressView.Open(); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnAppend() |
||||
{ |
||||
appendView.Open(); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnAddSound() |
||||
{ |
||||
addSoundView.Open(); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnWatermark() |
||||
{ |
||||
watermarkView.Open(); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnDirectInput(string commands) |
||||
{ |
||||
FFmpegCommands.DirectInput(commands); |
||||
} |
||||
|
||||
//FFmpeg processing callbacks |
||||
//------------------------------ |
||||
|
||||
//Begining of video processing |
||||
public void OnStart() |
||||
{ |
||||
defaultHandler.OnStart(); |
||||
progressView.OnStart(); |
||||
} |
||||
|
||||
//You can make custom progress bar here (parse msg) |
||||
public void OnProgress(string msg) |
||||
{ |
||||
defaultHandler.OnProgress(msg); |
||||
progressView.OnProgress(msg); |
||||
Console.Print(msg); |
||||
} |
||||
|
||||
//Notify user about failure here |
||||
public void OnFailure(string msg) |
||||
{ |
||||
defaultHandler.OnFailure(msg); |
||||
progressView.OnFailure(msg); |
||||
Console.Print(msg); |
||||
} |
||||
|
||||
//Notify user about success here |
||||
public void OnSuccess(string msg) |
||||
{ |
||||
defaultHandler.OnSuccess(msg); |
||||
progressView.OnSuccess(msg); |
||||
Console.Print(msg); |
||||
} |
||||
|
||||
//Last callback - do whatever you need next |
||||
public void OnFinish() |
||||
{ |
||||
defaultHandler.OnFinish(); |
||||
progressView.OnFinish(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 788c25183b80f3d4bb132b0694c0771a |
||||
timeCreated: 1494105909 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 042171e577ff27c4aaa1dd2bf0a05748 |
||||
timeCreated: 1493981686 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 7c58e117e7adf4dae8a12d9c0d4f1c02 |
||||
folderAsset: yes |
||||
timeCreated: 1507149392 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,41 @@
|
||||
using UnityEngine; |
||||
using UnityEngine.UI; |
||||
|
||||
namespace FFmpeg.Demo |
||||
{ |
||||
/// <summary> |
||||
/// This class role is to avoid overcome of vertex limit |
||||
/// on Output Text component if text is too big. |
||||
/// </summary> |
||||
public class Console : MonoBehaviour |
||||
{ |
||||
static Console self; |
||||
public Text output; |
||||
public Scrollbar vertical; |
||||
const int UNITY_VERTS_LIMIT = 65000; |
||||
const int CHAR_MIN = 2048, CHAR_MAX = UNITY_VERTS_LIMIT / 4 - 1; |
||||
[Range(CHAR_MIN, CHAR_MAX)] |
||||
public int outputCharLimit = |
||||
|
||||
#if UNITY_ANDROID && !UNITY_EDITOR |
||||
CHAR_MAX / 5; |
||||
#else |
||||
CHAR_MAX; |
||||
#endif |
||||
|
||||
void Awake() |
||||
{ |
||||
self = this; |
||||
} |
||||
|
||||
public static void Print(string msg) |
||||
{ |
||||
if(msg.Length > self.outputCharLimit) |
||||
{ |
||||
msg = msg.Remove(0, msg.Length - self.outputCharLimit); |
||||
} |
||||
self.output.text = msg; |
||||
self.vertical.value = 0; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 89821a064a6fa4d50b6506fe48249acb |
||||
timeCreated: 1507396708 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,20 @@
|
||||
using UnityEngine; |
||||
using UnityEngine.UI; |
||||
using UnityEngine.Events; |
||||
|
||||
namespace FFmpeg.Demo |
||||
{ |
||||
public class DefaultFieldInitializer : MonoBehaviour |
||||
{ |
||||
[System.Serializable] |
||||
public class SetEvent : UnityEvent<string> { } |
||||
|
||||
public Text placeholder; |
||||
public SetEvent setter; |
||||
|
||||
public void Awake() |
||||
{ |
||||
setter.Invoke(placeholder.text); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 574f61f4cd99649c69c561d45989c0bc |
||||
timeCreated: 1507149435 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 84fc004a531344509b7c2fd3b1541fde |
||||
folderAsset: yes |
||||
timeCreated: 1507106644 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,33 @@
|
||||
using UnityEngine; |
||||
using UnityEngine.UI; |
||||
using UnityEngine.Events; |
||||
|
||||
namespace FFmpeg.Demo.IOS |
||||
{ |
||||
public class IOSInputView : MonoBehaviour |
||||
{ |
||||
[System.Serializable] |
||||
public class PathEvent : UnityEvent<string> { } |
||||
|
||||
public Text iosPath; |
||||
public PathEvent pathSetter; |
||||
|
||||
public void OnPress() |
||||
{ |
||||
#if UNITY_IOS && !UNITY_EDITOR |
||||
IOSVideoPicker.GetVideoPath((string path) => |
||||
{ |
||||
iosPath.text = path; |
||||
pathSetter.Invoke(path); |
||||
}); |
||||
#endif |
||||
} |
||||
|
||||
#if !UNITY_IOS || UNITY_EDITOR |
||||
void Awake() |
||||
{ |
||||
gameObject.SetActive(false); |
||||
} |
||||
#endif |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 352db635e0f954120ba92862e90392e9 |
||||
timeCreated: 1507104741 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,37 @@
|
||||
using UnityEngine; |
||||
using UnityEngine.UI; |
||||
using UnityEngine.Events; |
||||
|
||||
namespace FFmpeg.Demo.IOS |
||||
{ |
||||
public class IOSOutputView : MonoBehaviour |
||||
{ |
||||
[System.Serializable] |
||||
public class PathEvent : UnityEvent<string> { } |
||||
|
||||
public Text iosDirectory; |
||||
public Text fileNamePlaceholder; |
||||
public PathEvent pathSetter; |
||||
|
||||
void Awake() |
||||
{ |
||||
#if UNITY_IOS && !UNITY_EDITOR |
||||
//It's a default sanbox place to keep Application files (Documents directory) |
||||
//https://developer.apple.com/library/content/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html |
||||
iosDirectory.text = Application.persistentDataPath + "/"; |
||||
OnFileNameInput(fileNamePlaceholder.text); |
||||
#else |
||||
gameObject.SetActive(false); |
||||
#endif |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Is called from InputField (inspector) as well. |
||||
/// </summary> |
||||
/// <param name="fileName">File name.</param> |
||||
public void OnFileNameInput(string fileName) |
||||
{ |
||||
pathSetter.Invoke(iosDirectory.text + fileName); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 48ba9ca9e7fbc4fd290aaf8fc41aeac4 |
||||
timeCreated: 1507104741 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,61 @@
|
||||
using System; |
||||
using System.Runtime.InteropServices; |
||||
using UnityEngine; |
||||
|
||||
namespace FFmpeg.Demo.IOS |
||||
{ |
||||
//Should be placed in the scene for callbacks initialization |
||||
public class IOSVideoPicker : MonoBehaviour |
||||
{ |
||||
#if UNITY_IOS && !UNITY_EDITOR |
||||
static Action<string> Callback; |
||||
|
||||
//https://forums.macrumors.com/threads/function-pointers-in-obj-c.253962/ |
||||
//void get_video_path(void (* callback)(const char*)); |
||||
[DllImport("__Internal")] |
||||
static extern int get_video_path(IOSCallback callback); |
||||
//void play(const char* path); |
||||
[DllImport("__Internal")] |
||||
static extern int play(string path); |
||||
|
||||
delegate void IOSCallback(string msg); |
||||
[AOT.MonoPInvokeCallback(typeof(IOSCallback))] |
||||
static void IOSCallbacFunc(string msg) |
||||
{ |
||||
Debug.Log("Unity receive video path: " + msg); |
||||
Callback(msg); |
||||
} |
||||
|
||||
public static void GetVideoPath(Action<string> _callback) |
||||
{ |
||||
get_video_path(IOSCallbacFunc); |
||||
Callback = _callback; |
||||
} |
||||
|
||||
public static void Play(string path) |
||||
{ |
||||
play(path); |
||||
} |
||||
#else |
||||
//Dummy Interface |
||||
//------------------------------ |
||||
|
||||
public static void GetVideoPath(Action<string> _callback) |
||||
{ |
||||
UnSupportedWarn(); |
||||
} |
||||
|
||||
public static void Play(string path) |
||||
{ |
||||
UnSupportedWarn(); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
static void UnSupportedWarn() |
||||
{ |
||||
Debug.LogWarning("IOSVideoPicker can't be used on " + Application.platform); |
||||
} |
||||
#endif |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 2db24719e44a44f05a3acbcfc039d7a3 |
||||
timeCreated: 1507104816 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: d2113178d991c404a94c0f608a7744aa |
||||
folderAsset: yes |
||||
timeCreated: 1507107406 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,238 @@
|
||||
%YAML 1.1 |
||||
%TAG !u! tag:unity3d.com,2011: |
||||
--- !u!1001 &100100000 |
||||
Prefab: |
||||
m_ObjectHideFlags: 1 |
||||
serializedVersion: 2 |
||||
m_Modification: |
||||
m_TransformParent: {fileID: 0} |
||||
m_Modifications: [] |
||||
m_RemovedComponents: [] |
||||
m_ParentPrefab: {fileID: 0} |
||||
m_RootGameObject: {fileID: 1366992365377538} |
||||
m_IsPrefabParent: 1 |
||||
--- !u!1 &1366992365377538 |
||||
GameObject: |
||||
m_ObjectHideFlags: 0 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
serializedVersion: 5 |
||||
m_Component: |
||||
- component: {fileID: 224795041860870388} |
||||
- component: {fileID: 222977176845462168} |
||||
- component: {fileID: 114310260466390926} |
||||
- component: {fileID: 114133034749596262} |
||||
- component: {fileID: 114887395005721756} |
||||
m_Layer: 5 |
||||
m_Name: IOSInput |
||||
m_TagString: Untagged |
||||
m_Icon: {fileID: 0} |
||||
m_NavMeshLayer: 0 |
||||
m_StaticEditorFlags: 0 |
||||
m_IsActive: 1 |
||||
--- !u!1 &1609924854286520 |
||||
GameObject: |
||||
m_ObjectHideFlags: 0 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
serializedVersion: 5 |
||||
m_Component: |
||||
- component: {fileID: 224123063233508026} |
||||
- component: {fileID: 222751091658479230} |
||||
- component: {fileID: 114451707763942402} |
||||
m_Layer: 5 |
||||
m_Name: IOSPathText |
||||
m_TagString: Untagged |
||||
m_Icon: {fileID: 0} |
||||
m_NavMeshLayer: 0 |
||||
m_StaticEditorFlags: 0 |
||||
m_IsActive: 1 |
||||
--- !u!114 &114133034749596262 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1366992365377538} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 1392445389, guid: f70555f144d8491a825f0804e09c671c, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
m_Navigation: |
||||
m_Mode: 3 |
||||
m_SelectOnUp: {fileID: 0} |
||||
m_SelectOnDown: {fileID: 0} |
||||
m_SelectOnLeft: {fileID: 0} |
||||
m_SelectOnRight: {fileID: 0} |
||||
m_Transition: 1 |
||||
m_Colors: |
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1} |
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} |
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} |
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} |
||||
m_ColorMultiplier: 1 |
||||
m_FadeDuration: 0.1 |
||||
m_SpriteState: |
||||
m_HighlightedSprite: {fileID: 0} |
||||
m_PressedSprite: {fileID: 0} |
||||
m_DisabledSprite: {fileID: 0} |
||||
m_AnimationTriggers: |
||||
m_NormalTrigger: Normal |
||||
m_HighlightedTrigger: Highlighted |
||||
m_PressedTrigger: Pressed |
||||
m_DisabledTrigger: Disabled |
||||
m_Interactable: 1 |
||||
m_TargetGraphic: {fileID: 114310260466390926} |
||||
m_OnClick: |
||||
m_PersistentCalls: |
||||
m_Calls: |
||||
- m_Target: {fileID: 114887395005721756} |
||||
m_MethodName: OnPress |
||||
m_Mode: 1 |
||||
m_Arguments: |
||||
m_ObjectArgument: {fileID: 0} |
||||
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine |
||||
m_IntArgument: 0 |
||||
m_FloatArgument: 0 |
||||
m_StringArgument: |
||||
m_BoolArgument: 0 |
||||
m_CallState: 2 |
||||
m_TypeName: UnityEngine.UI.Button+ButtonClickedEvent, UnityEngine.UI, Version=1.0.0.0, |
||||
Culture=neutral, PublicKeyToken=null |
||||
--- !u!114 &114310260466390926 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1366992365377538} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
m_Material: {fileID: 0} |
||||
m_Color: {r: 1, g: 1, b: 1, a: 1} |
||||
m_RaycastTarget: 1 |
||||
m_OnCullStateChanged: |
||||
m_PersistentCalls: |
||||
m_Calls: [] |
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, |
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null |
||||
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} |
||||
m_Type: 1 |
||||
m_PreserveAspect: 0 |
||||
m_FillCenter: 1 |
||||
m_FillMethod: 4 |
||||
m_FillAmount: 1 |
||||
m_FillClockwise: 1 |
||||
m_FillOrigin: 0 |
||||
--- !u!114 &114451707763942402 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1609924854286520} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
m_Material: {fileID: 0} |
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} |
||||
m_RaycastTarget: 0 |
||||
m_OnCullStateChanged: |
||||
m_PersistentCalls: |
||||
m_Calls: [] |
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, |
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null |
||||
m_FontData: |
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} |
||||
m_FontSize: 14 |
||||
m_FontStyle: 0 |
||||
m_BestFit: 0 |
||||
m_MinSize: 10 |
||||
m_MaxSize: 40 |
||||
m_Alignment: 4 |
||||
m_AlignByGeometry: 0 |
||||
m_RichText: 0 |
||||
m_HorizontalOverflow: 0 |
||||
m_VerticalOverflow: 1 |
||||
m_LineSpacing: 1 |
||||
m_Text: Tap to select input path... |
||||
--- !u!114 &114887395005721756 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1366992365377538} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 11500000, guid: 352db635e0f954120ba92862e90392e9, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
iosPath: {fileID: 114451707763942402} |
||||
pathSetter: |
||||
m_PersistentCalls: |
||||
m_Calls: |
||||
- m_Target: {fileID: 0} |
||||
m_MethodName: OnInputPath |
||||
m_Mode: 0 |
||||
m_Arguments: |
||||
m_ObjectArgument: {fileID: 0} |
||||
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine |
||||
m_IntArgument: 0 |
||||
m_FloatArgument: 0 |
||||
m_StringArgument: |
||||
m_BoolArgument: 0 |
||||
m_CallState: 2 |
||||
m_TypeName: IOSHelpers.IOSInputView+PathEvent, Assembly-CSharp, Version=0.0.0.0, |
||||
Culture=neutral, PublicKeyToken=null |
||||
--- !u!222 &222751091658479230 |
||||
CanvasRenderer: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1609924854286520} |
||||
--- !u!222 &222977176845462168 |
||||
CanvasRenderer: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1366992365377538} |
||||
--- !u!224 &224123063233508026 |
||||
RectTransform: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1609924854286520} |
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} |
||||
m_LocalPosition: {x: 0, y: 0, z: 0} |
||||
m_LocalScale: {x: 1, y: 1, z: 1} |
||||
m_Children: [] |
||||
m_Father: {fileID: 224795041860870388} |
||||
m_RootOrder: 0 |
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
||||
m_AnchorMin: {x: 0, y: 0} |
||||
m_AnchorMax: {x: 1, y: 1} |
||||
m_AnchoredPosition: {x: 0, y: 0} |
||||
m_SizeDelta: {x: -40, y: 0} |
||||
m_Pivot: {x: 0.5, y: 0.5} |
||||
--- !u!224 &224795041860870388 |
||||
RectTransform: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1366992365377538} |
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} |
||||
m_LocalPosition: {x: 0, y: 0, z: 0} |
||||
m_LocalScale: {x: 1, y: 1, z: 1} |
||||
m_Children: |
||||
- {fileID: 224123063233508026} |
||||
m_Father: {fileID: 0} |
||||
m_RootOrder: 0 |
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
||||
m_AnchorMin: {x: 0, y: 0} |
||||
m_AnchorMax: {x: 1, y: 1} |
||||
m_AnchoredPosition: {x: 0, y: 0} |
||||
m_SizeDelta: {x: 0, y: 0} |
||||
m_Pivot: {x: 0.5, y: 0.5} |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: d2fadff82e7f64f5587168ff20ec1b8b |
||||
timeCreated: 1507107812 |
||||
licenseType: Store |
||||
NativeFormatImporter: |
||||
mainObjectFileID: 100100000 |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,480 @@
|
||||
%YAML 1.1 |
||||
%TAG !u! tag:unity3d.com,2011: |
||||
--- !u!1001 &100100000 |
||||
Prefab: |
||||
m_ObjectHideFlags: 1 |
||||
serializedVersion: 2 |
||||
m_Modification: |
||||
m_TransformParent: {fileID: 0} |
||||
m_Modifications: [] |
||||
m_RemovedComponents: [] |
||||
m_ParentPrefab: {fileID: 0} |
||||
m_RootGameObject: {fileID: 1779034530262534} |
||||
m_IsPrefabParent: 1 |
||||
--- !u!1 &1007465926259496 |
||||
GameObject: |
||||
m_ObjectHideFlags: 0 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
serializedVersion: 5 |
||||
m_Component: |
||||
- component: {fileID: 224962100563648776} |
||||
- component: {fileID: 222968313683413782} |
||||
- component: {fileID: 114121671962571394} |
||||
m_Layer: 5 |
||||
m_Name: IOSOutputDirectoryhText |
||||
m_TagString: Untagged |
||||
m_Icon: {fileID: 0} |
||||
m_NavMeshLayer: 0 |
||||
m_StaticEditorFlags: 0 |
||||
m_IsActive: 1 |
||||
--- !u!1 &1636594625183688 |
||||
GameObject: |
||||
m_ObjectHideFlags: 0 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
serializedVersion: 5 |
||||
m_Component: |
||||
- component: {fileID: 224478192069367840} |
||||
- component: {fileID: 222558921929390396} |
||||
- component: {fileID: 114277750469832814} |
||||
- component: {fileID: 114685840400327800} |
||||
m_Layer: 5 |
||||
m_Name: FileNameInputField |
||||
m_TagString: Untagged |
||||
m_Icon: {fileID: 0} |
||||
m_NavMeshLayer: 0 |
||||
m_StaticEditorFlags: 0 |
||||
m_IsActive: 1 |
||||
--- !u!1 &1669835665522936 |
||||
GameObject: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
serializedVersion: 5 |
||||
m_Component: |
||||
- component: {fileID: 224295240365544530} |
||||
- component: {fileID: 222840003665681444} |
||||
- component: {fileID: 114944245965835412} |
||||
m_Layer: 5 |
||||
m_Name: FileNameText |
||||
m_TagString: Untagged |
||||
m_Icon: {fileID: 0} |
||||
m_NavMeshLayer: 0 |
||||
m_StaticEditorFlags: 0 |
||||
m_IsActive: 1 |
||||
--- !u!1 &1779034530262534 |
||||
GameObject: |
||||
m_ObjectHideFlags: 0 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
serializedVersion: 5 |
||||
m_Component: |
||||
- component: {fileID: 224846410253742780} |
||||
- component: {fileID: 222562783839953332} |
||||
- component: {fileID: 114943617362427144} |
||||
- component: {fileID: 114359303860719142} |
||||
m_Layer: 5 |
||||
m_Name: IOSOutput |
||||
m_TagString: Untagged |
||||
m_Icon: {fileID: 0} |
||||
m_NavMeshLayer: 0 |
||||
m_StaticEditorFlags: 0 |
||||
m_IsActive: 1 |
||||
--- !u!1 &1806189027617334 |
||||
GameObject: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
serializedVersion: 5 |
||||
m_Component: |
||||
- component: {fileID: 224976311432168394} |
||||
- component: {fileID: 222737882607692760} |
||||
- component: {fileID: 114058606850818050} |
||||
m_Layer: 5 |
||||
m_Name: FileNamePlaceholder |
||||
m_TagString: Untagged |
||||
m_Icon: {fileID: 0} |
||||
m_NavMeshLayer: 0 |
||||
m_StaticEditorFlags: 0 |
||||
m_IsActive: 1 |
||||
--- !u!114 &114058606850818050 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1806189027617334} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
m_Material: {fileID: 0} |
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} |
||||
m_RaycastTarget: 1 |
||||
m_OnCullStateChanged: |
||||
m_PersistentCalls: |
||||
m_Calls: [] |
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, |
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null |
||||
m_FontData: |
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} |
||||
m_FontSize: 14 |
||||
m_FontStyle: 2 |
||||
m_BestFit: 0 |
||||
m_MinSize: 10 |
||||
m_MaxSize: 40 |
||||
m_Alignment: 0 |
||||
m_AlignByGeometry: 0 |
||||
m_RichText: 1 |
||||
m_HorizontalOverflow: 0 |
||||
m_VerticalOverflow: 0 |
||||
m_LineSpacing: 1 |
||||
m_Text: Output.MOV |
||||
--- !u!114 &114121671962571394 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1007465926259496} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
m_Material: {fileID: 0} |
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} |
||||
m_RaycastTarget: 0 |
||||
m_OnCullStateChanged: |
||||
m_PersistentCalls: |
||||
m_Calls: [] |
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, |
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null |
||||
m_FontData: |
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} |
||||
m_FontSize: 14 |
||||
m_FontStyle: 0 |
||||
m_BestFit: 0 |
||||
m_MinSize: 10 |
||||
m_MaxSize: 40 |
||||
m_Alignment: 5 |
||||
m_AlignByGeometry: 0 |
||||
m_RichText: 0 |
||||
m_HorizontalOverflow: 0 |
||||
m_VerticalOverflow: 1 |
||||
m_LineSpacing: 1 |
||||
m_Text: Initialization at runtime from Application.persistentData / |
||||
--- !u!114 &114277750469832814 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1636594625183688} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
m_Material: {fileID: 0} |
||||
m_Color: {r: 1, g: 1, b: 1, a: 1} |
||||
m_RaycastTarget: 1 |
||||
m_OnCullStateChanged: |
||||
m_PersistentCalls: |
||||
m_Calls: [] |
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, |
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null |
||||
m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} |
||||
m_Type: 1 |
||||
m_PreserveAspect: 0 |
||||
m_FillCenter: 1 |
||||
m_FillMethod: 4 |
||||
m_FillAmount: 1 |
||||
m_FillClockwise: 1 |
||||
m_FillOrigin: 0 |
||||
--- !u!114 &114359303860719142 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1779034530262534} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 11500000, guid: 48ba9ca9e7fbc4fd290aaf8fc41aeac4, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
iosDirectory: {fileID: 114121671962571394} |
||||
fileNamePlaceholder: {fileID: 114058606850818050} |
||||
pathSetter: |
||||
m_PersistentCalls: |
||||
m_Calls: |
||||
- m_Target: {fileID: 0} |
||||
m_MethodName: OnOutputPath |
||||
m_Mode: 0 |
||||
m_Arguments: |
||||
m_ObjectArgument: {fileID: 0} |
||||
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine |
||||
m_IntArgument: 0 |
||||
m_FloatArgument: 0 |
||||
m_StringArgument: |
||||
m_BoolArgument: 0 |
||||
m_CallState: 2 |
||||
m_TypeName: IOSHelpers.IOSOutputView+PathEvent, Assembly-CSharp, Version=0.0.0.0, |
||||
Culture=neutral, PublicKeyToken=null |
||||
--- !u!114 &114685840400327800 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1636594625183688} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 575553740, guid: f70555f144d8491a825f0804e09c671c, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
m_Navigation: |
||||
m_Mode: 3 |
||||
m_SelectOnUp: {fileID: 0} |
||||
m_SelectOnDown: {fileID: 0} |
||||
m_SelectOnLeft: {fileID: 0} |
||||
m_SelectOnRight: {fileID: 0} |
||||
m_Transition: 1 |
||||
m_Colors: |
||||
m_NormalColor: {r: 1, g: 1, b: 1, a: 1} |
||||
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} |
||||
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} |
||||
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} |
||||
m_ColorMultiplier: 1 |
||||
m_FadeDuration: 0.1 |
||||
m_SpriteState: |
||||
m_HighlightedSprite: {fileID: 0} |
||||
m_PressedSprite: {fileID: 0} |
||||
m_DisabledSprite: {fileID: 0} |
||||
m_AnimationTriggers: |
||||
m_NormalTrigger: Normal |
||||
m_HighlightedTrigger: Highlighted |
||||
m_PressedTrigger: Pressed |
||||
m_DisabledTrigger: Disabled |
||||
m_Interactable: 1 |
||||
m_TargetGraphic: {fileID: 114277750469832814} |
||||
m_TextComponent: {fileID: 114944245965835412} |
||||
m_Placeholder: {fileID: 114058606850818050} |
||||
m_ContentType: 0 |
||||
m_InputType: 0 |
||||
m_AsteriskChar: 42 |
||||
m_KeyboardType: 0 |
||||
m_LineType: 0 |
||||
m_HideMobileInput: 0 |
||||
m_CharacterValidation: 0 |
||||
m_CharacterLimit: 0 |
||||
m_OnEndEdit: |
||||
m_PersistentCalls: |
||||
m_Calls: |
||||
- m_Target: {fileID: 114359303860719142} |
||||
m_MethodName: OnFileNameInput |
||||
m_Mode: 0 |
||||
m_Arguments: |
||||
m_ObjectArgument: {fileID: 0} |
||||
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine |
||||
m_IntArgument: 0 |
||||
m_FloatArgument: 0 |
||||
m_StringArgument: |
||||
m_BoolArgument: 0 |
||||
m_CallState: 2 |
||||
m_TypeName: UnityEngine.UI.InputField+SubmitEvent, UnityEngine.UI, Version=1.0.0.0, |
||||
Culture=neutral, PublicKeyToken=null |
||||
m_OnValueChanged: |
||||
m_PersistentCalls: |
||||
m_Calls: [] |
||||
m_TypeName: UnityEngine.UI.InputField+OnChangeEvent, UnityEngine.UI, Version=1.0.0.0, |
||||
Culture=neutral, PublicKeyToken=null |
||||
m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} |
||||
m_CustomCaretColor: 0 |
||||
m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} |
||||
m_Text: |
||||
m_CaretBlinkRate: 0.85 |
||||
m_CaretWidth: 1 |
||||
m_ReadOnly: 0 |
||||
--- !u!114 &114943617362427144 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1779034530262534} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
m_Material: {fileID: 0} |
||||
m_Color: {r: 1, g: 1, b: 1, a: 1} |
||||
m_RaycastTarget: 1 |
||||
m_OnCullStateChanged: |
||||
m_PersistentCalls: |
||||
m_Calls: [] |
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, |
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null |
||||
m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} |
||||
m_Type: 1 |
||||
m_PreserveAspect: 0 |
||||
m_FillCenter: 1 |
||||
m_FillMethod: 4 |
||||
m_FillAmount: 1 |
||||
m_FillClockwise: 1 |
||||
m_FillOrigin: 0 |
||||
--- !u!114 &114944245965835412 |
||||
MonoBehaviour: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1669835665522936} |
||||
m_Enabled: 1 |
||||
m_EditorHideFlags: 0 |
||||
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} |
||||
m_Name: |
||||
m_EditorClassIdentifier: |
||||
m_Material: {fileID: 0} |
||||
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} |
||||
m_RaycastTarget: 1 |
||||
m_OnCullStateChanged: |
||||
m_PersistentCalls: |
||||
m_Calls: [] |
||||
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, |
||||
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null |
||||
m_FontData: |
||||
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} |
||||
m_FontSize: 14 |
||||
m_FontStyle: 0 |
||||
m_BestFit: 0 |
||||
m_MinSize: 10 |
||||
m_MaxSize: 40 |
||||
m_Alignment: 0 |
||||
m_AlignByGeometry: 0 |
||||
m_RichText: 0 |
||||
m_HorizontalOverflow: 1 |
||||
m_VerticalOverflow: 0 |
||||
m_LineSpacing: 1 |
||||
m_Text: |
||||
--- !u!222 &222558921929390396 |
||||
CanvasRenderer: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1636594625183688} |
||||
--- !u!222 &222562783839953332 |
||||
CanvasRenderer: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1779034530262534} |
||||
--- !u!222 &222737882607692760 |
||||
CanvasRenderer: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1806189027617334} |
||||
--- !u!222 &222840003665681444 |
||||
CanvasRenderer: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1669835665522936} |
||||
--- !u!222 &222968313683413782 |
||||
CanvasRenderer: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1007465926259496} |
||||
--- !u!224 &224295240365544530 |
||||
RectTransform: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1669835665522936} |
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} |
||||
m_LocalPosition: {x: 0, y: 0, z: 0} |
||||
m_LocalScale: {x: 1, y: 1, z: 1} |
||||
m_Children: [] |
||||
m_Father: {fileID: 224478192069367840} |
||||
m_RootOrder: 1 |
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
||||
m_AnchorMin: {x: 0, y: 0} |
||||
m_AnchorMax: {x: 1, y: 1} |
||||
m_AnchoredPosition: {x: 0, y: -0.5} |
||||
m_SizeDelta: {x: -20, y: -13} |
||||
m_Pivot: {x: 0.5, y: 0.5} |
||||
--- !u!224 &224478192069367840 |
||||
RectTransform: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1636594625183688} |
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} |
||||
m_LocalPosition: {x: 0, y: 0, z: 0} |
||||
m_LocalScale: {x: 1, y: 1, z: 1} |
||||
m_Children: |
||||
- {fileID: 224976311432168394} |
||||
- {fileID: 224295240365544530} |
||||
m_Father: {fileID: 224846410253742780} |
||||
m_RootOrder: 1 |
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
||||
m_AnchorMin: {x: 0.7, y: 0} |
||||
m_AnchorMax: {x: 1, y: 1} |
||||
m_AnchoredPosition: {x: -2.5, y: 0} |
||||
m_SizeDelta: {x: -5, y: -10} |
||||
m_Pivot: {x: 0.5, y: 0.5} |
||||
--- !u!224 &224846410253742780 |
||||
RectTransform: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1779034530262534} |
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} |
||||
m_LocalPosition: {x: 0, y: 0, z: 0} |
||||
m_LocalScale: {x: 1, y: 1, z: 1} |
||||
m_Children: |
||||
- {fileID: 224962100563648776} |
||||
- {fileID: 224478192069367840} |
||||
m_Father: {fileID: 0} |
||||
m_RootOrder: 0 |
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
||||
m_AnchorMin: {x: 0, y: 0} |
||||
m_AnchorMax: {x: 1, y: 1} |
||||
m_AnchoredPosition: {x: 0, y: 0} |
||||
m_SizeDelta: {x: 0, y: 0} |
||||
m_Pivot: {x: 0.5, y: 0.5} |
||||
--- !u!224 &224962100563648776 |
||||
RectTransform: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1007465926259496} |
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} |
||||
m_LocalPosition: {x: 0, y: 0, z: 0} |
||||
m_LocalScale: {x: 1, y: 1, z: 1} |
||||
m_Children: [] |
||||
m_Father: {fileID: 224846410253742780} |
||||
m_RootOrder: 0 |
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
||||
m_AnchorMin: {x: 0, y: 0} |
||||
m_AnchorMax: {x: 0.7, y: 1} |
||||
m_AnchoredPosition: {x: 0, y: 0} |
||||
m_SizeDelta: {x: -10, y: -10} |
||||
m_Pivot: {x: 0.5, y: 0.5} |
||||
--- !u!224 &224976311432168394 |
||||
RectTransform: |
||||
m_ObjectHideFlags: 1 |
||||
m_PrefabParentObject: {fileID: 0} |
||||
m_PrefabInternal: {fileID: 100100000} |
||||
m_GameObject: {fileID: 1806189027617334} |
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} |
||||
m_LocalPosition: {x: 0, y: 0, z: 0} |
||||
m_LocalScale: {x: 1, y: 1, z: 1} |
||||
m_Children: [] |
||||
m_Father: {fileID: 224478192069367840} |
||||
m_RootOrder: 0 |
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} |
||||
m_AnchorMin: {x: 0, y: 0} |
||||
m_AnchorMax: {x: 1, y: 1} |
||||
m_AnchoredPosition: {x: 0, y: -0.5} |
||||
m_SizeDelta: {x: -20, y: -13} |
||||
m_Pivot: {x: 0.5, y: 0.5} |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: b4713d32e9fae409e9d66658aadd8d37 |
||||
timeCreated: 1507108057 |
||||
licenseType: Store |
||||
NativeFormatImporter: |
||||
mainObjectFileID: 100100000 |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 57c3a441e94a5e942a4c04961ecfdbf3 |
||||
folderAsset: yes |
||||
timeCreated: 1494249023 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,66 @@
|
||||
using UnityEngine; |
||||
using UnityEngine.UI; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace FFmpeg.Demo |
||||
{ |
||||
public class AddSoundView : MonoBehaviour |
||||
{ |
||||
public Dropdown modeDropdown; |
||||
|
||||
public InputField inputVideoField; |
||||
public InputField inputAudioField; |
||||
public InputField outputField; |
||||
|
||||
SoundData config = new SoundData(); |
||||
bool fastMode; |
||||
|
||||
//------------------------------ |
||||
|
||||
void Awake() |
||||
{ |
||||
OnFastOrFull(modeDropdown.value); |
||||
} |
||||
|
||||
public void Open() |
||||
{ |
||||
gameObject.SetActive(true); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnOutputPath(string fullPath) |
||||
{ |
||||
config.outputPath = fullPath; |
||||
} |
||||
|
||||
public void OnSoundInputPath(string fullPath) |
||||
{ |
||||
config.soundPath = fullPath; |
||||
} |
||||
|
||||
public void OnVideoInputPath(string fullPath) |
||||
{ |
||||
config.inputPath = fullPath; |
||||
} |
||||
|
||||
public void OnFastOrFull(int fast) |
||||
{ |
||||
fastMode = fast > 0; |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnAddSound() |
||||
{ |
||||
if (fastMode) |
||||
FFmpegCommands.AddSoundFast(config); |
||||
else |
||||
FFmpegCommands.AddSoundFull(config); |
||||
|
||||
gameObject.SetActive(false); |
||||
} |
||||
|
||||
//------------------------------ |
||||
} |
||||
} |
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 8bdbc1eb5af34411682753c14ac36fb8 |
||||
timeCreated: 1516657192 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,93 @@
|
||||
using UnityEngine; |
||||
using UnityEngine.UI; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace FFmpeg.Demo |
||||
{ |
||||
public class AppendView : MonoBehaviour |
||||
{ |
||||
public Dropdown modeDropdown; |
||||
|
||||
public InputField inputFieldOrigin; |
||||
List<InputField> inputFields = new List<InputField>(); |
||||
int MIN_INPUT_VIDEOS = 2; |
||||
|
||||
AppendData config = new AppendData(); |
||||
bool fastMode; |
||||
|
||||
//------------------------------ |
||||
|
||||
void Awake() |
||||
{ |
||||
OnFastOrFull(modeDropdown.value); |
||||
|
||||
for (int i = 0; i < MIN_INPUT_VIDEOS; ++i) |
||||
{ |
||||
OnAddInput(); |
||||
} |
||||
} |
||||
|
||||
public void Open() |
||||
{ |
||||
gameObject.SetActive(true); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnFastOrFull(int fast) |
||||
{ |
||||
fastMode = fast > 0; |
||||
} |
||||
|
||||
public void OnOutputPath(string fullPath) |
||||
{ |
||||
config.outputPath = fullPath; |
||||
} |
||||
|
||||
public void OnAddInput() |
||||
{ |
||||
InputField inputInstance = |
||||
Instantiate(inputFieldOrigin, inputFieldOrigin.transform.parent); |
||||
inputInstance.gameObject.SetActive(true); |
||||
inputInstance.transform.SetSiblingIndex(inputFields.Count); |
||||
inputFields.Add(inputInstance); |
||||
} |
||||
|
||||
public void OnRemoveInput() |
||||
{ |
||||
if (inputFields.Count > MIN_INPUT_VIDEOS) |
||||
{ |
||||
int lastIndex = inputFields.Count - 1; |
||||
Destroy(inputFields[lastIndex].gameObject); |
||||
inputFields.RemoveAt(lastIndex); |
||||
} |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnAppend() |
||||
{ |
||||
config.inputPaths.Clear(); |
||||
|
||||
//Collect input paths. NOTE: Videos should be in same orientation. |
||||
foreach (InputField inputField in inputFields) |
||||
{ |
||||
config.inputPaths.Add( |
||||
#if UNITY_IOS && !UNITY_EDITOR |
||||
inputField.gameObject.GetComponentInChildren<IOS.IOSInputView>().iosPath.text); |
||||
#else |
||||
inputField.text); |
||||
#endif |
||||
} |
||||
|
||||
if (fastMode) |
||||
FFmpegCommands.AppendFast(config); |
||||
else |
||||
FFmpegCommands.AppendFull(config); |
||||
|
||||
gameObject.SetActive(false); |
||||
} |
||||
|
||||
//------------------------------ |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 287c73a2a75ea41cfb451d55429eab87 |
||||
timeCreated: 1507307185 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,55 @@
|
||||
using UnityEngine; |
||||
using UnityEngine.UI; |
||||
|
||||
namespace FFmpeg.Demo |
||||
{ |
||||
public class CompressView : MonoBehaviour |
||||
{ |
||||
CompressionData config = new CompressionData(); |
||||
public InputField crfField; |
||||
public Slider amountSlider; |
||||
const int MIN_CRF = 0; |
||||
const int MAX_CRF = 51; |
||||
|
||||
//------------------------------ |
||||
|
||||
public void Open() |
||||
{ |
||||
gameObject.SetActive(true); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnInputPath(string fullPath) |
||||
{ |
||||
config.inputPath = fullPath; |
||||
} |
||||
|
||||
public void OnCRF(string crf) |
||||
{ |
||||
config.crf = int.Parse(crf); |
||||
amountSlider.value = (float)config.crf / MAX_CRF; |
||||
} |
||||
|
||||
public void OnOutputPath(string fullPath) |
||||
{ |
||||
config.outputPath = fullPath; |
||||
} |
||||
|
||||
public void OnAmount(float amount) |
||||
{ |
||||
config.crf = (int)Mathf.Lerp(MIN_CRF, MAX_CRF, amount); |
||||
crfField.text = config.crf.ToString(); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnCompress() |
||||
{ |
||||
FFmpegCommands.Compress(config); |
||||
gameObject.SetActive(false); |
||||
} |
||||
|
||||
//------------------------------ |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 80205bdbb30eb492b9be1cea89cb0a11 |
||||
timeCreated: 1507241702 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,39 @@
|
||||
using UnityEngine; |
||||
|
||||
namespace FFmpeg.Demo |
||||
{ |
||||
public class ConvertView : MonoBehaviour |
||||
{ |
||||
BaseData config = new BaseData(); |
||||
|
||||
//------------------------------ |
||||
|
||||
public void Open() |
||||
{ |
||||
gameObject.SetActive(true); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnInputPath(string fullPath) |
||||
{ |
||||
config.inputPath = fullPath; |
||||
} |
||||
|
||||
public void OnOutputPath(string fullPath) |
||||
{ |
||||
config.outputPath = fullPath; |
||||
} |
||||
|
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnConvert() |
||||
{ |
||||
FFmpegCommands.Convert(config); |
||||
gameObject.SetActive(false); |
||||
} |
||||
|
||||
//------------------------------ |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 4f4bbdf330ec34a1293b9ab6be476164 |
||||
timeCreated: 1497479113 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,48 @@
|
||||
using UnityEngine; |
||||
|
||||
namespace FFmpeg.Demo |
||||
{ |
||||
public class DecodeView : MonoBehaviour |
||||
{ |
||||
DecodeEncodeData config = new DecodeEncodeData(); |
||||
|
||||
//------------------------------ |
||||
|
||||
public void Open() |
||||
{ |
||||
gameObject.SetActive(true); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnImagesPathInput(string fullPath) |
||||
{ |
||||
config.outputPath = fullPath; |
||||
} |
||||
|
||||
public void OnSoundPathInput(string fullPath) |
||||
{ |
||||
config.soundPath = fullPath; |
||||
} |
||||
|
||||
public void OnVideoPathInput(string fullPath) |
||||
{ |
||||
config.inputPath = fullPath; |
||||
} |
||||
|
||||
public void OnFPSInput(string fps) |
||||
{ |
||||
config.fps = float.Parse(fps); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnDecode() |
||||
{ |
||||
FFmpegCommands.Decode(config); |
||||
gameObject.SetActive(false); |
||||
} |
||||
|
||||
//------------------------------ |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: bdbc743f356767c4b93b6c815c8c410b |
||||
timeCreated: 1494263099 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,48 @@
|
||||
using UnityEngine; |
||||
|
||||
namespace FFmpeg.Demo |
||||
{ |
||||
public class EncodeView : MonoBehaviour |
||||
{ |
||||
DecodeEncodeData config = new DecodeEncodeData(); |
||||
|
||||
//------------------------------ |
||||
|
||||
public void Open() |
||||
{ |
||||
gameObject.SetActive(true); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnImagesPathInput(string fullPath) |
||||
{ |
||||
config.inputPath = fullPath; |
||||
} |
||||
|
||||
public void OnSoundPathInput(string fullPath) |
||||
{ |
||||
config.soundPath = fullPath; |
||||
} |
||||
|
||||
public void OnOutputPathInput(string fullPath) |
||||
{ |
||||
config.outputPath = fullPath; |
||||
} |
||||
|
||||
public void OnFPSInput(string fps) |
||||
{ |
||||
config.fps = float.Parse(fps); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnEncode() |
||||
{ |
||||
FFmpegCommands.Encode(config); |
||||
gameObject.SetActive(false); |
||||
} |
||||
|
||||
//------------------------------ |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 35e9b8a2094f7ee4097bc7fc10421eea |
||||
timeCreated: 1494249185 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,77 @@
|
||||
using UnityEngine; |
||||
using UnityEngine.UI; |
||||
|
||||
namespace FFmpeg.Demo |
||||
{ |
||||
public class ProgressView : MonoBehaviour, IFFmpegHandler |
||||
{ |
||||
public Text progressField; |
||||
public Image progressBar; |
||||
public Color normalColor, failureColor; |
||||
|
||||
float durationBuffer, progress; |
||||
bool? success; |
||||
|
||||
//PUBLIC |
||||
//------------------------------ |
||||
|
||||
public void OnStart() |
||||
{ |
||||
success = null; |
||||
progressBar.color = normalColor; |
||||
durationBuffer = progress = 0; |
||||
UpdateBar(); |
||||
progressField.text = "Started."; |
||||
} |
||||
|
||||
public void OnProgress(string msg) |
||||
{ |
||||
if (success == null) |
||||
{ |
||||
FFmpegProgressParser.Parse(msg, ref durationBuffer, ref progress); |
||||
progressField.text = "Progress: " + (int)(progress * 100) + "% / 100%"; |
||||
UpdateBar(); |
||||
} |
||||
} |
||||
|
||||
public void OnFailure(string msg) |
||||
{ |
||||
OnProgress(msg); |
||||
success = false; |
||||
} |
||||
|
||||
public void OnSuccess(string msg) |
||||
{ |
||||
OnProgress(msg); |
||||
success = true; |
||||
} |
||||
|
||||
public void OnFinish() |
||||
{ |
||||
progress = 1; |
||||
UpdateBar(); |
||||
if (success == true) |
||||
{ |
||||
progressField.text = "Success!"; |
||||
} |
||||
else if (success == false) |
||||
{ |
||||
progressField.text = "Failure."; |
||||
progressBar.color = failureColor; |
||||
} |
||||
else |
||||
{ |
||||
progressField.text = "Finish."; |
||||
} |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
void UpdateBar() |
||||
{ |
||||
Vector3 scale = Vector3.one; |
||||
scale.x = progress; |
||||
progressBar.transform.localScale = scale; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 0957afaa7934b49cca017f054dee9f2d |
||||
timeCreated: 1507187957 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,48 @@
|
||||
using UnityEngine; |
||||
|
||||
namespace FFmpeg.Demo |
||||
{ |
||||
public class TrimView : MonoBehaviour |
||||
{ |
||||
TrimData config = new TrimData(); |
||||
|
||||
//------------------------------ |
||||
|
||||
public void Open() |
||||
{ |
||||
gameObject.SetActive(true); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnInputPath(string fullPath) |
||||
{ |
||||
config.inputPath = fullPath; |
||||
} |
||||
|
||||
public void OnStartTime(string time) |
||||
{ |
||||
config.fromTime = time; |
||||
} |
||||
|
||||
public void OnOutputPath(string fullPath) |
||||
{ |
||||
config.outputPath = fullPath; |
||||
} |
||||
|
||||
public void OnDuration(string duration) |
||||
{ |
||||
config.durationSec = int.Parse(duration); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnTrim() |
||||
{ |
||||
FFmpegCommands.Trim(config); |
||||
gameObject.SetActive(false); |
||||
} |
||||
|
||||
//------------------------------ |
||||
} |
||||
} |
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 78e16832b52e3448b95fcd516e821912 |
||||
timeCreated: 1497475042 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,80 @@
|
||||
using UnityEngine; |
||||
using UnityEngine.UI; |
||||
|
||||
namespace FFmpeg.Demo |
||||
{ |
||||
public class WatermarkView : MonoBehaviour |
||||
{ |
||||
WatermarkData config = new WatermarkData(); |
||||
|
||||
public Text imageScaleText; |
||||
public Slider imageScaleSlider; |
||||
|
||||
public Text xPosNormalText; |
||||
public Slider xPosNormalSlider; |
||||
|
||||
public Text yPosNormalText; |
||||
public Slider yPosNormalSlider; |
||||
|
||||
//------------------------------ |
||||
|
||||
void Awake() |
||||
{ |
||||
OnImageScale(imageScaleSlider.value); |
||||
OnXPositionNormalized(xPosNormalSlider.value); |
||||
OnYPositionNormalized(yPosNormalSlider.value); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void Open() |
||||
{ |
||||
gameObject.SetActive(true); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnVideoInputPath(string fullPath) |
||||
{ |
||||
config.inputPath = fullPath; |
||||
} |
||||
|
||||
public void OnImageInputPath(string fullPath) |
||||
{ |
||||
config.imagePath = fullPath; |
||||
} |
||||
|
||||
public void OnOutputPath(string fullPath) |
||||
{ |
||||
config.outputPath = fullPath; |
||||
} |
||||
|
||||
public void OnImageScale(float multiplier) |
||||
{ |
||||
config.imageScale = multiplier; |
||||
imageScaleText.text = "Image Scale: " + multiplier; |
||||
} |
||||
|
||||
public void OnXPositionNormalized(float x) |
||||
{ |
||||
config.xPosNormal = x; |
||||
xPosNormalText.text = "Normalized X of image center: " + x; |
||||
} |
||||
|
||||
public void OnYPositionNormalized(float y) |
||||
{ |
||||
config.yPosNormal = y; |
||||
yPosNormalText.text = "Normalized Y of image center: " + y; |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnWatermark() |
||||
{ |
||||
FFmpegCommands.Watermark(config); |
||||
gameObject.SetActive(false); |
||||
} |
||||
|
||||
//------------------------------ |
||||
} |
||||
} |
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 2dd2a5c885dff4e6fa6afbf87a61bde8 |
||||
timeCreated: 1516668642 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,266 @@
|
||||
using UnityEngine; |
||||
using System; |
||||
using System.IO; |
||||
using System.Text; |
||||
|
||||
namespace FFmpeg.Demo.REC |
||||
{ |
||||
//[RequireComponent(typeof(RecMicAudio), typeof(RecSystemAudio))] |
||||
public class FFmpegREC : MonoBehaviour, IFFmpegHandler |
||||
{ |
||||
//Data |
||||
[Header("Targeted FPS")] |
||||
public int FPS = 30; |
||||
float actualFPS; |
||||
[Header("0 for max resolution")] |
||||
public int width ; |
||||
public int height ; |
||||
[Header("Change before initialization")] |
||||
public RecAudioSource recAudioSource = RecAudioSource.System; |
||||
Rect camRect; |
||||
|
||||
//References |
||||
IRecAudio soundRecorder; |
||||
Texture2D frameBuffer; |
||||
|
||||
//Paths |
||||
const string FILE_FORMAT = "{0}_Frame.jpg"; |
||||
const string SOUND_NAME = "RecordedAudio.wav"; |
||||
[HideInInspector] |
||||
public string VIDEO_NAME = "ScreenCapture.mp4"; |
||||
string cashDir, imgFilePathFormat, firstImgFilePath, soundPath, outputVideoPath; |
||||
|
||||
//Variables |
||||
int framesCount; |
||||
float startTime, frameInterval, frameTimer, totalTime; |
||||
|
||||
public bool isREC { get; private set; } |
||||
public bool isProducing { get; private set; } |
||||
#if !UNITY_EDITOR |
||||
int initialWidth, initialHeight; |
||||
public bool overrideResolution { get { return width > 0 || height > 0; } } |
||||
#endif |
||||
|
||||
//References |
||||
Action<string> onOutput, onFinish; |
||||
|
||||
//PUBLIC INTERFACE |
||||
//------------------------------ |
||||
public RecSavePanel RecSavePanel; |
||||
public void Init(Action<string> _onOutput, Action<string> _onFinish) |
||||
{ |
||||
//Subscription to FFmpeg callbacks |
||||
FFmpegParser.Handler = this; |
||||
width = Screen.width; |
||||
height = Screen.height; |
||||
//Paths initialization |
||||
string path = Application.streamingAssetsPath + "/RECFile/" + GameSettings.othersSettings.mode.ToString() + "/" + CurrentUserInfo.room.Id.ToString(); |
||||
if (!Directory.Exists(path)) |
||||
{ |
||||
Directory.CreateDirectory(path); |
||||
} |
||||
cashDir = Path.Combine(path, "RecordingCash"); |
||||
imgFilePathFormat = Path.Combine(cashDir, FILE_FORMAT); |
||||
firstImgFilePath = String.Format(imgFilePathFormat, "%0d"); |
||||
soundPath = Path.Combine(cashDir, SOUND_NAME); |
||||
outputVideoPath = Path.Combine(path, VIDEO_NAME); |
||||
|
||||
#if !UNITY_EDITOR |
||||
initialWidth = Screen.width; |
||||
initialHeight = Screen.height; |
||||
#endif |
||||
|
||||
//Sound source initialization |
||||
if (recAudioSource == RecAudioSource.Mic) |
||||
{ |
||||
soundRecorder = GetComponent<RecMicAudio>(); |
||||
} |
||||
else if (recAudioSource == RecAudioSource.System) |
||||
{ |
||||
soundRecorder = GetComponent<RecSystemAudio>(); |
||||
} |
||||
else if (recAudioSource == RecAudioSource.None) |
||||
{ |
||||
soundRecorder = null; |
||||
} |
||||
|
||||
onOutput = _onOutput; |
||||
onFinish = _onFinish; |
||||
} |
||||
|
||||
void Clear() |
||||
{ |
||||
if (Directory.Exists(cashDir)) |
||||
Directory.Delete(cashDir, true); |
||||
} |
||||
|
||||
public void StartREC() |
||||
{ |
||||
if (!isREC && !isProducing) |
||||
{ |
||||
Clear(); |
||||
Directory.CreateDirectory(cashDir); |
||||
Debug.Log("CashDir created: " + cashDir); |
||||
|
||||
#if !UNITY_EDITOR |
||||
if (overrideResolution) |
||||
{ |
||||
//Low level operation of resolution change |
||||
Screen.SetResolution(width, height, Screen.fullScreen); |
||||
} |
||||
else |
||||
#endif |
||||
{ |
||||
width = Screen.width; |
||||
height = Screen.height; |
||||
} |
||||
|
||||
frameBuffer = new Texture2D(width, height, TextureFormat.RGB24, false, true); |
||||
camRect = new Rect(0, 0, width, height); |
||||
startTime = Time.time; |
||||
framesCount = 0; |
||||
frameInterval = 1.0f / FPS; |
||||
frameTimer = frameInterval; |
||||
|
||||
isREC = true; |
||||
|
||||
if (recAudioSource != RecAudioSource.None) |
||||
{ |
||||
soundRecorder.StartRecording(); |
||||
} |
||||
RecSavePanel.BeginTime = TIME_SYNC.time; |
||||
} |
||||
} |
||||
|
||||
public void StopREC() |
||||
{ |
||||
isREC = false; |
||||
isProducing = true; |
||||
|
||||
totalTime = Time.time - startTime; |
||||
actualFPS = framesCount / totalTime; |
||||
|
||||
Debug.Log("Actual FPS: " + actualFPS); |
||||
|
||||
if (recAudioSource != RecAudioSource.None) |
||||
{ |
||||
soundRecorder.StopRecording(soundPath); |
||||
} |
||||
|
||||
RecSavePanel.gameObject.SetActive(true); |
||||
//CreateVideo(); |
||||
|
||||
#if !UNITY_EDITOR |
||||
if (overrideResolution) |
||||
//Return to initial screen resolution |
||||
Screen.SetResolution(initialWidth, initialHeight, Screen.fullScreen); |
||||
#endif |
||||
} |
||||
|
||||
//INTERNAL IMPLEMENTATION |
||||
//------------------------------ |
||||
|
||||
void OnPostRender() |
||||
{ |
||||
if (isREC && (frameTimer += Time.deltaTime) > frameInterval) |
||||
{ |
||||
frameTimer -= frameInterval; |
||||
|
||||
frameBuffer.ReadPixels(camRect, 0, 0); |
||||
|
||||
File.WriteAllBytes(NextImgFilePath(), frameBuffer.EncodeToJPG()); |
||||
} |
||||
} |
||||
|
||||
string NextImgFilePath() |
||||
{ |
||||
return String.Format(imgFilePathFormat, framesCount++); |
||||
} |
||||
|
||||
public void CreateVideo() |
||||
{ |
||||
StringBuilder command = new StringBuilder(); |
||||
|
||||
Debug.Log("firstImgFilePath: " + firstImgFilePath); |
||||
Debug.Log("soundPath: " + soundPath); |
||||
Debug.Log("outputVideoPath:------------ " + outputVideoPath); |
||||
|
||||
//Input Image sequence params |
||||
command. |
||||
Append("-y -framerate "). |
||||
Append(actualFPS.ToString()). |
||||
Append(" -f image2 -i "). |
||||
Append(AddQuotation(firstImgFilePath)); |
||||
|
||||
//Input Audio params |
||||
if (recAudioSource != RecAudioSource.None) |
||||
{ |
||||
command. |
||||
Append(" -i "). |
||||
Append(AddQuotation(soundPath)). |
||||
Append(" -ss 0 -t "). |
||||
Append(totalTime); |
||||
} |
||||
|
||||
//Output Video params |
||||
command. |
||||
Append(" -vcodec libx264 -crf 25 -pix_fmt yuv420p "). |
||||
Append(AddQuotation(outputVideoPath)); |
||||
|
||||
Debug.Log(command.ToString()); |
||||
|
||||
FFmpegCommands.DirectInput(command.ToString()); |
||||
} |
||||
|
||||
string AddQuotation(string path) |
||||
{ |
||||
if (string.IsNullOrEmpty(path)) |
||||
{ |
||||
throw new Exception("Empty path."); |
||||
} |
||||
#if UNITY_EDITOR || UNITY_STANDALONE |
||||
const char DOUBLE_QUOTATION = '\"'; |
||||
if (path[0] != DOUBLE_QUOTATION) |
||||
{ |
||||
return DOUBLE_QUOTATION + path + DOUBLE_QUOTATION; |
||||
} |
||||
#endif |
||||
return path; |
||||
} |
||||
|
||||
//FFmpeg processing callbacks |
||||
//------------------------------ |
||||
|
||||
//Begining of video processing |
||||
public void OnStart() |
||||
{ |
||||
onOutput("VideoProducing Started\n"); |
||||
} |
||||
|
||||
//You can make custom progress bar here (parse msg) |
||||
public void OnProgress(string msg) |
||||
{ |
||||
onOutput(msg); |
||||
} |
||||
|
||||
//Notify user about failure here |
||||
public void OnFailure(string msg) |
||||
{ |
||||
onOutput(msg); |
||||
} |
||||
|
||||
//Notify user about success here |
||||
public void OnSuccess(string msg) |
||||
{ |
||||
onOutput(msg); |
||||
} |
||||
|
||||
//Last callback - do whatever you need next |
||||
public void OnFinish() |
||||
{ |
||||
onFinish(outputVideoPath); |
||||
Clear(); |
||||
isProducing = false; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 9b7b769dfdd064a84b4ec5fd4af122eb |
||||
timeCreated: 1516472529 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 0be586934272646008da2c2ca2bf77a6 |
||||
timeCreated: 1516482292 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 1cae6f020443246aeb7a7271db72b337 |
||||
folderAsset: yes |
||||
timeCreated: 1516482867 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 9864c0efb53af4a0499b95a5e09d447a |
||||
folderAsset: yes |
||||
timeCreated: 1521911844 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,166 @@
|
||||
using System; |
||||
using System.IO; |
||||
using System.Collections.Generic; |
||||
using UnityEngine; |
||||
|
||||
public enum RecAudioSource |
||||
{ |
||||
Mic, |
||||
System, |
||||
None |
||||
} |
||||
|
||||
public interface IRecAudio |
||||
{ |
||||
void StartRecording(); |
||||
void StopRecording(string savePath); |
||||
} |
||||
|
||||
public static class SavWav |
||||
{ |
||||
const int HEADER_SIZE = 44; |
||||
|
||||
public static void Save(string path, AudioClip clip) |
||||
{ |
||||
// Make sure directory exists if user is saving to sub dir. |
||||
Directory.CreateDirectory(Path.GetDirectoryName(path)); |
||||
|
||||
using (var fileStream = CreateEmpty(path)) |
||||
{ |
||||
ConvertAndWrite(fileStream, clip); |
||||
|
||||
WriteHeader(fileStream, clip); |
||||
} |
||||
} |
||||
|
||||
public static AudioClip TrimSilence(AudioClip clip, float min) |
||||
{ |
||||
var samples = new float[clip.samples]; |
||||
|
||||
clip.GetData(samples, 0); |
||||
|
||||
return TrimSilence(new List<float>(samples), min, clip.channels, clip.frequency); |
||||
} |
||||
|
||||
public static AudioClip TrimSilence(List<float> samples, float min, int channels, int hz) |
||||
{ |
||||
int i; |
||||
|
||||
for (i = 0; i < samples.Count; i++) |
||||
{ |
||||
if (Mathf.Abs(samples[i]) > min) |
||||
{ |
||||
break; |
||||
} |
||||
} |
||||
|
||||
samples.RemoveRange(0, i); |
||||
|
||||
for (i = samples.Count - 1; i > 0; i--) |
||||
{ |
||||
if (Mathf.Abs(samples[i]) > min) |
||||
{ |
||||
break; |
||||
} |
||||
} |
||||
|
||||
samples.RemoveRange(i, samples.Count - i); |
||||
|
||||
var clip = AudioClip.Create("TempClip", samples.Count, channels, hz, false); |
||||
|
||||
clip.SetData(samples.ToArray(), 0); |
||||
|
||||
return clip; |
||||
} |
||||
|
||||
static FileStream CreateEmpty(string filepath) |
||||
{ |
||||
var fileStream = new FileStream(filepath, FileMode.Create); |
||||
byte emptyByte = new byte(); |
||||
|
||||
for (int i = 0; i < HEADER_SIZE; i++) //preparing the header |
||||
{ |
||||
fileStream.WriteByte(emptyByte); |
||||
} |
||||
|
||||
return fileStream; |
||||
} |
||||
|
||||
static void ConvertAndWrite(FileStream fileStream, AudioClip clip) |
||||
{ |
||||
var samples = new float[clip.samples]; |
||||
|
||||
clip.GetData(samples, 0); |
||||
|
||||
Int16[] intData = new Int16[samples.Length]; |
||||
//converting in 2 float[] steps to Int16[], //then Int16[] to Byte[] |
||||
|
||||
Byte[] bytesData = new Byte[samples.Length * 2]; |
||||
//bytesData array is twice the size of |
||||
//dataSource array because a float converted in Int16 is 2 bytes. |
||||
|
||||
int rescaleFactor = 32767; //to convert float to Int16 |
||||
|
||||
for (int i = 0; i < samples.Length; i++) |
||||
{ |
||||
intData[i] = (short)(samples[i] * rescaleFactor); |
||||
Byte[] byteArr = new Byte[2]; |
||||
byteArr = BitConverter.GetBytes(intData[i]); |
||||
byteArr.CopyTo(bytesData, i * 2); |
||||
} |
||||
|
||||
fileStream.Write(bytesData, 0, bytesData.Length); |
||||
} |
||||
|
||||
static void WriteHeader(FileStream fileStream, AudioClip clip) |
||||
{ |
||||
var hz = clip.frequency; |
||||
var channels = clip.channels; |
||||
var samples = clip.samples; |
||||
|
||||
fileStream.Seek(0, SeekOrigin.Begin); |
||||
|
||||
Byte[] riff = System.Text.Encoding.UTF8.GetBytes("RIFF"); |
||||
fileStream.Write(riff, 0, 4); |
||||
|
||||
Byte[] chunkSize = BitConverter.GetBytes(fileStream.Length - 8); |
||||
fileStream.Write(chunkSize, 0, 4); |
||||
|
||||
Byte[] wave = System.Text.Encoding.UTF8.GetBytes("WAVE"); |
||||
fileStream.Write(wave, 0, 4); |
||||
|
||||
Byte[] fmt = System.Text.Encoding.UTF8.GetBytes("fmt "); |
||||
fileStream.Write(fmt, 0, 4); |
||||
|
||||
Byte[] subChunk1 = BitConverter.GetBytes(16); |
||||
fileStream.Write(subChunk1, 0, 4); |
||||
|
||||
//UInt16 two = 2; |
||||
UInt16 one = 1; |
||||
|
||||
Byte[] audioFormat = BitConverter.GetBytes(one); |
||||
fileStream.Write(audioFormat, 0, 2); |
||||
|
||||
Byte[] numChannels = BitConverter.GetBytes(channels); |
||||
fileStream.Write(numChannels, 0, 2); |
||||
|
||||
Byte[] sampleRate = BitConverter.GetBytes(hz); |
||||
fileStream.Write(sampleRate, 0, 4); |
||||
|
||||
Byte[] byteRate = BitConverter.GetBytes(hz * channels * 2); // sampleRate * bytesPerSample*number of channels, here 44100*2*2 |
||||
fileStream.Write(byteRate, 0, 4); |
||||
|
||||
UInt16 blockAlign = (ushort)(channels * 2); |
||||
fileStream.Write(BitConverter.GetBytes(blockAlign), 0, 2); |
||||
|
||||
UInt16 bps = 16; |
||||
Byte[] bitsPerSample = BitConverter.GetBytes(bps); |
||||
fileStream.Write(bitsPerSample, 0, 2); |
||||
|
||||
Byte[] datastring = System.Text.Encoding.UTF8.GetBytes("data"); |
||||
fileStream.Write(datastring, 0, 4); |
||||
|
||||
Byte[] subChunk2 = BitConverter.GetBytes(samples * channels * 2); |
||||
fileStream.Write(subChunk2, 0, 4); |
||||
} |
||||
} |
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2 |
||||
guid: f2c408a08a9e6462eb1d1f4527cadb99 |
||||
timeCreated: 1521897562 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,18 @@
|
||||
using UnityEngine; |
||||
|
||||
public class RecMicAudio : MonoBehaviour, IRecAudio |
||||
{ |
||||
public int maxLength = 60; |
||||
AudioClip buffer; |
||||
|
||||
public void StartRecording() |
||||
{ |
||||
buffer = Microphone.Start(null, false, maxLength, AudioSettings.outputSampleRate); |
||||
} |
||||
|
||||
public void StopRecording(string savePath) |
||||
{ |
||||
Microphone.End(null); |
||||
SavWav.Save(savePath, buffer); |
||||
} |
||||
} |
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 93eb515ca8ff848149b46fb6ef378268 |
||||
timeCreated: 1521912146 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,45 @@
|
||||
using System.Collections.Generic; |
||||
using UnityEngine; |
||||
|
||||
public class RecSystemAudio : MonoBehaviour, IRecAudio |
||||
{ |
||||
List<float> audioData = new List<float>(); |
||||
float startTime; |
||||
int channelsCount; |
||||
|
||||
void Awake() |
||||
{ |
||||
enabled = false; |
||||
} |
||||
|
||||
public void StartRecording() |
||||
{ |
||||
enabled = true; |
||||
startTime = Time.time; |
||||
} |
||||
|
||||
void OnAudioFilterRead(float[] data, int channels) |
||||
{ |
||||
audioData.AddRange(data); |
||||
channelsCount = channels; |
||||
} |
||||
|
||||
public void StopRecording(string savePath) |
||||
{ |
||||
enabled = false; |
||||
int durationInSec = Mathf.CeilToInt(Time.time - startTime); |
||||
|
||||
//Create file |
||||
AudioClip buffer = |
||||
AudioClip.Create( |
||||
"SystemSound", |
||||
AudioSettings.outputSampleRate * channelsCount * durationInSec, |
||||
channelsCount, |
||||
AudioSettings.outputSampleRate, |
||||
false); |
||||
|
||||
buffer.SetData(audioData.ToArray(), 0); |
||||
|
||||
SavWav.Save(savePath, buffer); |
||||
} |
||||
} |
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2 |
||||
guid: c08765d6ae52f4fc3aa3b05ae8a4d5e1 |
||||
timeCreated: 1521911864 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,20 @@
|
||||
using UnityEngine; |
||||
|
||||
|
||||
namespace FFmpeg.Demo.REC |
||||
{ |
||||
public class RecDemoBall : MonoBehaviour |
||||
{ |
||||
public AudioClip ballHitSound; |
||||
public AudioSource source; |
||||
[Range(0, 1)] |
||||
public float voice = 0.5f; |
||||
public Rigidbody body; |
||||
|
||||
void OnCollisionEnter(Collision collision) |
||||
{ |
||||
source.PlayOneShot(ballHitSound, voice); |
||||
body.AddForce(Vector3.up * 10, ForceMode.Impulse); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2 |
||||
guid: dffdc94fb82a044be838a730bbe9913e |
||||
timeCreated: 1516482986 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 84a0a8a65744f4ed9b84c282ec847406 |
||||
folderAsset: yes |
||||
timeCreated: 1521897590 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
Binary file not shown.
@ -0,0 +1,24 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 706f365ed9b054bacb11e6041fc66921 |
||||
timeCreated: 1521897701 |
||||
licenseType: Store |
||||
AudioImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 6 |
||||
defaultSettings: |
||||
loadType: 0 |
||||
sampleRateSetting: 0 |
||||
sampleRateOverride: 44100 |
||||
compressionFormat: 1 |
||||
quality: 1 |
||||
conversionMode: 0 |
||||
platformSettingOverrides: {} |
||||
forceToMono: 0 |
||||
normalize: 1 |
||||
preloadAudioData: 1 |
||||
loadInBackground: 0 |
||||
ambisonic: 0 |
||||
3D: 1 |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
Binary file not shown.
@ -0,0 +1,24 @@
|
||||
fileFormatVersion: 2 |
||||
guid: d006f64530e2a4dd982785eb80e50bd0 |
||||
timeCreated: 1521898541 |
||||
licenseType: Store |
||||
AudioImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 6 |
||||
defaultSettings: |
||||
loadType: 0 |
||||
sampleRateSetting: 0 |
||||
sampleRateOverride: 44100 |
||||
compressionFormat: 1 |
||||
quality: 0.32999998 |
||||
conversionMode: 0 |
||||
platformSettingOverrides: {} |
||||
forceToMono: 0 |
||||
normalize: 1 |
||||
preloadAudioData: 1 |
||||
loadInBackground: 0 |
||||
ambisonic: 0 |
||||
3D: 1 |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 8d8b12296ee784d0d8225aac07bc95fb |
||||
folderAsset: yes |
||||
timeCreated: 1516482927 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,73 @@
|
||||
using UnityEngine; |
||||
using UnityEngine.UI; |
||||
|
||||
namespace FFmpeg.Demo.REC |
||||
{ |
||||
public class RECView : MonoBehaviour |
||||
{ |
||||
public FFmpegREC recLogic; |
||||
public Button startBtn, stopBtn; |
||||
public Text output; |
||||
const int charsLimit = 2000; |
||||
|
||||
//------------------------------ |
||||
|
||||
void Awake() |
||||
{ |
||||
recLogic.Init(Output, Finish); |
||||
startBtn.onClick.AddListener(OnStart); |
||||
stopBtn.onClick.AddListener(OnStop); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnStart() |
||||
{ |
||||
startBtn.interactable = false; |
||||
stopBtn.interactable = true; |
||||
recLogic.StartREC(); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
public void OnStop() |
||||
{ |
||||
stopBtn.interactable = false; |
||||
recLogic.StopREC(); |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
void Output(string msg) |
||||
{ |
||||
string newOutput = output.text + msg; |
||||
if (newOutput.Length > charsLimit) |
||||
newOutput = newOutput.Remove(0, newOutput.Length - charsLimit); |
||||
output.text = newOutput; |
||||
} |
||||
|
||||
public void Finish(string outputVideo) |
||||
{ |
||||
startBtn.interactable = true; |
||||
Debug.Log("Video saved to: " + outputVideo); |
||||
string localURL = "file://" + outputVideo; |
||||
#if (UNITY_IOS || UNITY_ANDROID) && !UNITY_EDITOR |
||||
Handheld.PlayFullScreenMovie( |
||||
localURL, |
||||
Color.black, |
||||
FullScreenMovieControlMode.Full, |
||||
FullScreenMovieScalingMode.AspectFit); |
||||
#else |
||||
Application.OpenURL(localURL); |
||||
#endif |
||||
} |
||||
|
||||
//------------------------------ |
||||
|
||||
void OnDestroy() |
||||
{ |
||||
startBtn.onClick.RemoveListener(OnStart); |
||||
stopBtn.onClick.RemoveListener(OnStop); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 15258e98e899e415f96864575352efaa |
||||
timeCreated: 1516471603 |
||||
licenseType: Store |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
Binary file not shown.
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: b15dea19382454d6c8f80d133bf35715 |
||||
timeCreated: 1497559589 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 6fdbfa610e74acf4da577bdf393e65d3 |
||||
folderAsset: yes |
||||
timeCreated: 1493981572 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 1808e651e7f37a94b9cc2ae788ec8e43 |
||||
folderAsset: yes |
||||
timeCreated: 1493981578 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||
package="com.botvinev.max.unityplugin" |
||||
android:versionCode="1" |
||||
android:versionName="1.0" > |
||||
|
||||
<uses-sdk |
||||
android:minSdkVersion="16" |
||||
android:targetSdkVersion="25" /> |
||||
|
||||
<!-- PERMISSIONS --> |
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> |
||||
|
||||
<application |
||||
android:allowBackup="true" |
||||
android:theme="@style/UnityThemeSelector" |
||||
android:icon="@drawable/app_icon" |
||||
android:label="@string/app_name" |
||||
android:debuggable="true"> |
||||
<activity android:name="com.unity3d.player.UnityPlayerActivity" |
||||
android:label="@string/app_name"> |
||||
<intent-filter> |
||||
<action android:name="android.intent.action.MAIN" /> |
||||
<category android:name="android.intent.category.LAUNCHER" /> |
||||
</intent-filter> |
||||
<meta-data android:name="unityplayer.UnityActivity" android:value="true" /> |
||||
<meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" /> |
||||
</activity> |
||||
</application> |
||||
|
||||
</manifest> |
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 9b365ebd3c6617f4396772472a76e85e |
||||
timeCreated: 1494006035 |
||||
licenseType: Store |
||||
TextScriptImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 8028de42c1bf349428dac1fce2fe3830 |
||||
folderAsset: yes |
||||
timeCreated: 1493981635 |
||||
licenseType: Store |
||||
DefaultImporter: |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
Binary file not shown.
@ -0,0 +1,33 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 557e8ec2ea5cbab4e9a2c135948b771a |
||||
timeCreated: 1494099391 |
||||
licenseType: Store |
||||
PluginImporter: |
||||
serializedVersion: 2 |
||||
iconMap: {} |
||||
executionOrder: {} |
||||
isPreloaded: 0 |
||||
isOverridable: 0 |
||||
platformData: |
||||
data: |
||||
first: |
||||
Android: Android |
||||
second: |
||||
enabled: 1 |
||||
settings: {} |
||||
data: |
||||
first: |
||||
Any: |
||||
second: |
||||
enabled: 0 |
||||
settings: {} |
||||
data: |
||||
first: |
||||
Editor: Editor |
||||
second: |
||||
enabled: 0 |
||||
settings: |
||||
DefaultValueInitialized: true |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue