Browse Source

添加录屏功能

master
杨栋梁 2 years ago
parent
commit
84c4e8e2f4
  1. 8
      Assets/FFmpeg.meta
  2. 9
      Assets/FFmpeg/Editor.meta
  3. 53
      Assets/FFmpeg/Editor/IOSPostBuild.cs
  4. 12
      Assets/FFmpeg/Editor/IOSPostBuild.cs.meta
  5. 28
      Assets/FFmpeg/Editor/MacPostBuild.cs
  6. 13
      Assets/FFmpeg/Editor/MacPostBuild.cs.meta
  7. 29
      Assets/FFmpeg/Editor/WinPostBuild.cs
  8. 13
      Assets/FFmpeg/Editor/WinPostBuild.cs.meta
  9. 77
      Assets/FFmpeg/FFmpeg.prefab
  10. 9
      Assets/FFmpeg/FFmpeg.prefab.meta
  11. 9
      Assets/FFmpeg/FFmpegCode.meta
  12. 9
      Assets/FFmpeg/FFmpegCode/FFmpegHelpers.meta
  13. 399
      Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegCommands.cs
  14. 12
      Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegCommands.cs.meta
  15. 53
      Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegConfigs.cs
  16. 12
      Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegConfigs.cs.meta
  17. 26
      Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegHandler.cs
  18. 12
      Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegHandler.cs.meta
  19. 82
      Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegParser.cs
  20. 12
      Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegParser.cs.meta
  21. 68
      Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegProgressParser.cs
  22. 12
      Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegProgressParser.cs.meta
  23. 9
      Assets/FFmpeg/FFmpegCode/FFmpegUtils.meta
  24. 221
      Assets/FFmpeg/FFmpegCode/FFmpegUtils/UnityThread.cs
  25. 12
      Assets/FFmpeg/FFmpegCode/FFmpegUtils/UnityThread.cs.meta
  26. 96
      Assets/FFmpeg/FFmpegCode/FFmpegWrapper.cs
  27. 12
      Assets/FFmpeg/FFmpegCode/FFmpegWrapper.cs.meta
  28. 9
      Assets/FFmpeg/FFmpegDemo.meta
  29. 137
      Assets/FFmpeg/FFmpegDemo/FFmpegDemo.cs
  30. 12
      Assets/FFmpeg/FFmpegDemo/FFmpegDemo.cs.meta
  31. 27664
      Assets/FFmpeg/FFmpegDemo/FFmpegDemo.unity
  32. 8
      Assets/FFmpeg/FFmpegDemo/FFmpegDemo.unity.meta
  33. 9
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers.meta
  34. 41
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/Console.cs
  35. 12
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/Console.cs.meta
  36. 20
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/DefaultFieldInitializer.cs
  37. 12
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/DefaultFieldInitializer.cs.meta
  38. 9
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/IOSDemoHelpers.meta
  39. 33
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/IOSDemoHelpers/IOSInputView.cs
  40. 12
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/IOSDemoHelpers/IOSInputView.cs.meta
  41. 37
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/IOSDemoHelpers/IOSOutputView.cs
  42. 12
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/IOSDemoHelpers/IOSOutputView.cs.meta
  43. 61
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/IOSDemoHelpers/IOSVideoPicker.cs
  44. 12
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/IOSDemoHelpers/IOSVideoPicker.cs.meta
  45. 9
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoPrefabs.meta
  46. 238
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoPrefabs/IOSInput.prefab
  47. 9
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoPrefabs/IOSInput.prefab.meta
  48. 480
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoPrefabs/IOSOutput.prefab
  49. 9
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoPrefabs/IOSOutput.prefab.meta
  50. 9
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView.meta
  51. 66
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/AddSoundView.cs
  52. 13
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/AddSoundView.cs.meta
  53. 93
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/AppendView.cs
  54. 12
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/AppendView.cs.meta
  55. 55
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/CompressView.cs
  56. 12
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/CompressView.cs.meta
  57. 39
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/ConvertView.cs
  58. 12
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/ConvertView.cs.meta
  59. 48
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/DecodeView.cs
  60. 12
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/DecodeView.cs.meta
  61. 48
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/EncodeView.cs
  62. 12
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/EncodeView.cs.meta
  63. 77
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/ProgressView.cs
  64. 12
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/ProgressView.cs.meta
  65. 48
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/TrimView.cs
  66. 12
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/TrimView.cs.meta
  67. 80
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/WatermarkView.cs
  68. 13
      Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/WatermarkView.cs.meta
  69. 266
      Assets/FFmpeg/FFmpegDemo/FFmpegREC.cs
  70. 13
      Assets/FFmpeg/FFmpegDemo/FFmpegREC.cs.meta
  71. 1273
      Assets/FFmpeg/FFmpegDemo/FFmpegREC.unity
  72. 9
      Assets/FFmpeg/FFmpegDemo/FFmpegREC.unity.meta
  73. 10
      Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers.meta
  74. 10
      Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers/RecAudio.meta
  75. 166
      Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers/RecAudio/RecAudio.cs
  76. 13
      Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers/RecAudio/RecAudio.cs.meta
  77. 18
      Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers/RecAudio/RecMicAudio.cs
  78. 13
      Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers/RecAudio/RecMicAudio.cs.meta
  79. 45
      Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers/RecAudio/RecSystemAudio.cs
  80. 13
      Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers/RecAudio/RecSystemAudio.cs.meta
  81. 20
      Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers/RecDemoBall.cs
  82. 13
      Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers/RecDemoBall.cs.meta
  83. 10
      Assets/FFmpeg/FFmpegDemo/FFmpegRECSound.meta
  84. BIN
      Assets/FFmpeg/FFmpegDemo/FFmpegRECSound/BallHit.wav
  85. 24
      Assets/FFmpeg/FFmpegDemo/FFmpegRECSound/BallHit.wav.meta
  86. BIN
      Assets/FFmpeg/FFmpegDemo/FFmpegRECSound/Music.wav
  87. 24
      Assets/FFmpeg/FFmpegDemo/FFmpegRECSound/Music.wav.meta
  88. 10
      Assets/FFmpeg/FFmpegDemo/FFmpegRECView.meta
  89. 73
      Assets/FFmpeg/FFmpegDemo/FFmpegRECView/RECView.cs
  90. 13
      Assets/FFmpeg/FFmpegDemo/FFmpegRECView/RECView.cs.meta
  91. BIN
      Assets/FFmpeg/GettingStarted.pdf
  92. 8
      Assets/FFmpeg/GettingStarted.pdf.meta
  93. 9
      Assets/FFmpeg/Plugins.meta
  94. 9
      Assets/FFmpeg/Plugins/Android.meta
  95. 32
      Assets/FFmpeg/Plugins/Android/AndroidManifest.xml
  96. 8
      Assets/FFmpeg/Plugins/Android/AndroidManifest.xml.meta
  97. 9
      Assets/FFmpeg/Plugins/Android/libs.meta
  98. BIN
      Assets/FFmpeg/Plugins/Android/libs/FFmpegAndroid-0.3.2.aar
  99. 33
      Assets/FFmpeg/Plugins/Android/libs/FFmpegAndroid-0.3.2.aar.meta
  100. BIN
      Assets/FFmpeg/Plugins/Android/libs/classes.jar
  101. Some files were not shown because too many files have changed in this diff Show More

8
Assets/FFmpeg.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 890f5ca9e9d84954c8d5da6c669e3316
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

9
Assets/FFmpeg/Editor.meta

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: fcccc3f00c645488881030aed989c9d4
folderAsset: yes
timeCreated: 1505748953
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

53
Assets/FFmpeg/Editor/IOSPostBuild.cs

@ -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

12
Assets/FFmpeg/Editor/IOSPostBuild.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 359eb934d7023405cbeaa85319fb5366
timeCreated: 1505748977
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

28
Assets/FFmpeg/Editor/MacPostBuild.cs

@ -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

13
Assets/FFmpeg/Editor/MacPostBuild.cs.meta

@ -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:

29
Assets/FFmpeg/Editor/WinPostBuild.cs

@ -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

13
Assets/FFmpeg/Editor/WinPostBuild.cs.meta

@ -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:

77
Assets/FFmpeg/FFmpeg.prefab

@ -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:

9
Assets/FFmpeg/FFmpeg.prefab.meta

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 62e3898569660b0479c5f3232ee87134
timeCreated: 1494108781
licenseType: Store
NativeFormatImporter:
mainObjectFileID: 100100000
userData:
assetBundleName:
assetBundleVariant:

9
Assets/FFmpeg/FFmpegCode.meta

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 798827c46ffc96742b0880c8d98f2522
folderAsset: yes
timeCreated: 1494106279
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/FFmpeg/FFmpegCode/FFmpegHelpers.meta

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 0d4de293ce7a70845944564e8e9e3958
folderAsset: yes
timeCreated: 1494105826
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

399
Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegCommands.cs

@ -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());
}
}

12
Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegCommands.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: bf4b2c3165228674f912efe2cff60995
timeCreated: 1494102306
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

53
Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegConfigs.cs

@ -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;
}
}

12
Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegConfigs.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 5205e809d4416734599a47b31c7abd8f
timeCreated: 1494257500
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

26
Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegHandler.cs

@ -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"); }
}
}

12
Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegHandler.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7a07f550e5b7fbf4e83a0f1d6aaffd1b
timeCreated: 1494104255
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

82
Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegParser.cs

@ -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);
}
}
}

12
Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegParser.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9952bc2f51fdc6849b6082018258f4fc
timeCreated: 1494102484
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

68
Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegProgressParser.cs

@ -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;
}
}
}

12
Assets/FFmpeg/FFmpegCode/FFmpegHelpers/FFmpegProgressParser.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e1c3db01c7a2e40b090e76640a57ec3f
timeCreated: 1507185808
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
Assets/FFmpeg/FFmpegCode/FFmpegUtils.meta

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: d3a31090f40b1459385ce1c12ac90828
folderAsset: yes
timeCreated: 1505946622
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

221
Assets/FFmpeg/FFmpegCode/FFmpegUtils/UnityThread.cs

@ -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;
}
}
}

12
Assets/FFmpeg/FFmpegCode/FFmpegUtils/UnityThread.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 1f3b5e6148f704c65aca6d4d300ec2dc
timeCreated: 1505946638
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

96
Assets/FFmpeg/FFmpegCode/FFmpegWrapper.cs

@ -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());
}
}
}
}

12
Assets/FFmpeg/FFmpegCode/FFmpegWrapper.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 414d4f09fac14ca4dadf24c3e2f296ff
timeCreated: 1493981673
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
Assets/FFmpeg/FFmpegDemo.meta

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 0ef485d93e4530c42b4b8577018f1aa7
folderAsset: yes
timeCreated: 1494248975
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

137
Assets/FFmpeg/FFmpegDemo/FFmpegDemo.cs

@ -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();
}
}
}

12
Assets/FFmpeg/FFmpegDemo/FFmpegDemo.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 788c25183b80f3d4bb132b0694c0771a
timeCreated: 1494105909
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

27664
Assets/FFmpeg/FFmpegDemo/FFmpegDemo.unity

File diff suppressed because it is too large Load Diff

8
Assets/FFmpeg/FFmpegDemo/FFmpegDemo.unity.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 042171e577ff27c4aaa1dd2bf0a05748
timeCreated: 1493981686
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers.meta

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 7c58e117e7adf4dae8a12d9c0d4f1c02
folderAsset: yes
timeCreated: 1507149392
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

41
Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/Console.cs

@ -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;
}
}
}

12
Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/Console.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 89821a064a6fa4d50b6506fe48249acb
timeCreated: 1507396708
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

20
Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/DefaultFieldInitializer.cs

@ -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);
}
}
}

12
Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/DefaultFieldInitializer.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 574f61f4cd99649c69c561d45989c0bc
timeCreated: 1507149435
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/IOSDemoHelpers.meta

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 84fc004a531344509b7c2fd3b1541fde
folderAsset: yes
timeCreated: 1507106644
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

33
Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/IOSDemoHelpers/IOSInputView.cs

@ -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
}
}

12
Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/IOSDemoHelpers/IOSInputView.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 352db635e0f954120ba92862e90392e9
timeCreated: 1507104741
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

37
Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/IOSDemoHelpers/IOSOutputView.cs

@ -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);
}
}
}

12
Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/IOSDemoHelpers/IOSOutputView.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 48ba9ca9e7fbc4fd290aaf8fc41aeac4
timeCreated: 1507104741
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

61
Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/IOSDemoHelpers/IOSVideoPicker.cs

@ -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
}
}

12
Assets/FFmpeg/FFmpegDemo/FFmpegDemoHelpers/IOSDemoHelpers/IOSVideoPicker.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 2db24719e44a44f05a3acbcfc039d7a3
timeCreated: 1507104816
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
Assets/FFmpeg/FFmpegDemo/FFmpegDemoPrefabs.meta

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: d2113178d991c404a94c0f608a7744aa
folderAsset: yes
timeCreated: 1507107406
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

238
Assets/FFmpeg/FFmpegDemo/FFmpegDemoPrefabs/IOSInput.prefab

@ -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}

9
Assets/FFmpeg/FFmpegDemo/FFmpegDemoPrefabs/IOSInput.prefab.meta

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: d2fadff82e7f64f5587168ff20ec1b8b
timeCreated: 1507107812
licenseType: Store
NativeFormatImporter:
mainObjectFileID: 100100000
userData:
assetBundleName:
assetBundleVariant:

480
Assets/FFmpeg/FFmpegDemo/FFmpegDemoPrefabs/IOSOutput.prefab

@ -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}

9
Assets/FFmpeg/FFmpegDemo/FFmpegDemoPrefabs/IOSOutput.prefab.meta

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: b4713d32e9fae409e9d66658aadd8d37
timeCreated: 1507108057
licenseType: Store
NativeFormatImporter:
mainObjectFileID: 100100000
userData:
assetBundleName:
assetBundleVariant:

9
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView.meta

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 57c3a441e94a5e942a4c04961ecfdbf3
folderAsset: yes
timeCreated: 1494249023
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

66
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/AddSoundView.cs

@ -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);
}
//------------------------------
}
}

13
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/AddSoundView.cs.meta

@ -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:

93
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/AppendView.cs

@ -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);
}
//------------------------------
}
}

12
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/AppendView.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 287c73a2a75ea41cfb451d55429eab87
timeCreated: 1507307185
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

55
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/CompressView.cs

@ -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);
}
//------------------------------
}
}

12
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/CompressView.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 80205bdbb30eb492b9be1cea89cb0a11
timeCreated: 1507241702
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

39
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/ConvertView.cs

@ -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);
}
//------------------------------
}
}

12
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/ConvertView.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4f4bbdf330ec34a1293b9ab6be476164
timeCreated: 1497479113
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

48
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/DecodeView.cs

@ -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);
}
//------------------------------
}
}

12
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/DecodeView.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: bdbc743f356767c4b93b6c815c8c410b
timeCreated: 1494263099
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

48
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/EncodeView.cs

@ -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);
}
//------------------------------
}
}

12
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/EncodeView.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 35e9b8a2094f7ee4097bc7fc10421eea
timeCreated: 1494249185
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

77
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/ProgressView.cs

@ -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;
}
}
}

12
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/ProgressView.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0957afaa7934b49cca017f054dee9f2d
timeCreated: 1507187957
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

48
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/TrimView.cs

@ -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);
}
//------------------------------
}
}

12
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/TrimView.cs.meta

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 78e16832b52e3448b95fcd516e821912
timeCreated: 1497475042
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

80
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/WatermarkView.cs

@ -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);
}
//------------------------------
}
}

13
Assets/FFmpeg/FFmpegDemo/FFmpegDemoView/WatermarkView.cs.meta

@ -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:

266
Assets/FFmpeg/FFmpegDemo/FFmpegREC.cs

@ -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;
}
}
}

13
Assets/FFmpeg/FFmpegDemo/FFmpegREC.cs.meta

@ -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:

1273
Assets/FFmpeg/FFmpegDemo/FFmpegREC.unity

File diff suppressed because it is too large Load Diff

9
Assets/FFmpeg/FFmpegDemo/FFmpegREC.unity.meta

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 0be586934272646008da2c2ca2bf77a6
timeCreated: 1516482292
licenseType: Store
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

10
Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers.meta

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 1cae6f020443246aeb7a7271db72b337
folderAsset: yes
timeCreated: 1516482867
licenseType: Store
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

10
Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers/RecAudio.meta

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 9864c0efb53af4a0499b95a5e09d447a
folderAsset: yes
timeCreated: 1521911844
licenseType: Store
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

166
Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers/RecAudio/RecAudio.cs

@ -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);
}
}

13
Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers/RecAudio/RecAudio.cs.meta

@ -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:

18
Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers/RecAudio/RecMicAudio.cs

@ -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);
}
}

13
Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers/RecAudio/RecMicAudio.cs.meta

@ -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:

45
Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers/RecAudio/RecSystemAudio.cs

@ -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);
}
}

13
Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers/RecAudio/RecSystemAudio.cs.meta

@ -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:

20
Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers/RecDemoBall.cs

@ -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);
}
}
}

13
Assets/FFmpeg/FFmpegDemo/FFmpegRECHelpers/RecDemoBall.cs.meta

@ -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:

10
Assets/FFmpeg/FFmpegDemo/FFmpegRECSound.meta

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 84a0a8a65744f4ed9b84c282ec847406
folderAsset: yes
timeCreated: 1521897590
licenseType: Store
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/FFmpeg/FFmpegDemo/FFmpegRECSound/BallHit.wav

Binary file not shown.

24
Assets/FFmpeg/FFmpegDemo/FFmpegRECSound/BallHit.wav.meta

@ -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:

BIN
Assets/FFmpeg/FFmpegDemo/FFmpegRECSound/Music.wav

Binary file not shown.

24
Assets/FFmpeg/FFmpegDemo/FFmpegRECSound/Music.wav.meta

@ -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:

10
Assets/FFmpeg/FFmpegDemo/FFmpegRECView.meta

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 8d8b12296ee784d0d8225aac07bc95fb
folderAsset: yes
timeCreated: 1516482927
licenseType: Store
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

73
Assets/FFmpeg/FFmpegDemo/FFmpegRECView/RECView.cs

@ -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);
}
}
}

13
Assets/FFmpeg/FFmpegDemo/FFmpegRECView/RECView.cs.meta

@ -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:

BIN
Assets/FFmpeg/GettingStarted.pdf

Binary file not shown.

8
Assets/FFmpeg/GettingStarted.pdf.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b15dea19382454d6c8f80d133bf35715
timeCreated: 1497559589
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/FFmpeg/Plugins.meta

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 6fdbfa610e74acf4da577bdf393e65d3
folderAsset: yes
timeCreated: 1493981572
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/FFmpeg/Plugins/Android.meta

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 1808e651e7f37a94b9cc2ae788ec8e43
folderAsset: yes
timeCreated: 1493981578
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

32
Assets/FFmpeg/Plugins/Android/AndroidManifest.xml

@ -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>

8
Assets/FFmpeg/Plugins/Android/AndroidManifest.xml.meta

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9b365ebd3c6617f4396772472a76e85e
timeCreated: 1494006035
licenseType: Store
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

9
Assets/FFmpeg/Plugins/Android/libs.meta

@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 8028de42c1bf349428dac1fce2fe3830
folderAsset: yes
timeCreated: 1493981635
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

BIN
Assets/FFmpeg/Plugins/Android/libs/FFmpegAndroid-0.3.2.aar

Binary file not shown.

33
Assets/FFmpeg/Plugins/Android/libs/FFmpegAndroid-0.3.2.aar.meta

@ -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:

BIN
Assets/FFmpeg/Plugins/Android/libs/classes.jar

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save