рдмреЛрдирд╕!
рдЗрд╕ рд▓реЗрдЦ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдЖрдк рди рдХреЗрд╡рд▓ рдпреВрдирд┐рдЯреА 3 рдбреА рдореЗрдВ рд╡реАрдбрд┐рдпреЛ рдХреИрдкреНрдЪрд░ рдХреЛ рдПрдореНрдмреЗрдб рдХрд░рдирд╛ рд╕реАрдЦреЗрдВрдЧреЗ, рдмрд▓реНрдХрд┐ рдПрдВрдбреНрд░реЙрдЗрдб рдХреЗ рд▓рд┐рдП рдПрдХрддрд╛ рдкреНрд▓рдЧрдЗрдиреНрд╕ рднреА рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдЕрдЧрд▓рд╛, рд╣рдо рдпреВрдирд┐рдЯреА 3 рдбреА рдореЗрдВ рд╡реАрдбрд┐рдпреЛ рдХреИрдкреНрдЪрд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджреЛ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗ:
1. рдкреВрд░реНрдг рд╕реНрдХреНрд░реАрди рдкреЛрд╕реНрдЯ рдкреНрд░рднрд╛рд╡ред рд╡рд┐рдзрд┐ рдХреЗрд╡рд▓ рдкреНрд░реЛ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдХрд╛рдо рдХрд░реЗрдЧреА, рдЬрдмрдХрд┐ рдПрдХрддрд╛ рдЬреАрдпреВрдЖрдИ рд╡реАрдбрд┐рдпреЛ рдореЗрдВ рдХреИрдкреНрдЪрд░ рдирд╣реАрдВ рдХреА рдЬрд╛рдПрдЧреА
2. рдПрдХ рдлреНрд░реЗрдо рдмрдлрд░ ( FrameBuffer ) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред рдпрд╣ рдпреВрдирд┐рдЯреА 3 рдбреА рдХреЗ рд╕рднреА рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░реЗрдЧрд╛, рдЬрд┐рд╕рдореЗрдВ рдкреЗрдб рдФрд░ рдлреНрд░реА рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рд╡реАрдбрд┐рдпреЛ рдореЗрдВ рдпреВрдирд┐рдЯреА рдЬреАрдпреВрдЖрдИ рдСрдмреНрдЬреЗрдХреНрдЯ рднреА рд░рд┐рдХреЙрд░реНрдб рдХрд┐рдП рдЬрд╛рдПрдВрдЧреЗред
рд╣рдореЗрдВ рдХреНрдпрд╛ рдЪрд╛рд╣рд┐рдП?
- рдпреВрдирд┐рдЯреА 3 рдбреА рд╕рдВрд╕реНрдХрд░рдг 4.3 рдкрд╣рд▓реЗ рдФрд░ рджреВрд╕рд░реЗ рддрд░реАрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░реЛ рд╕рдВрд╕реНрдХрд░рдг, рдпрд╛ рдПрдХ рдореБрдлреНрдд рд╕рдВрд╕реНрдХрд░рдг рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рдлреНрд░реЗрдо рдмрдлрд░ рд╡рд┐рдзрд┐ рдЙрдкрд▓рдмреНрдз рд╣реИ
- Android рдПрд╕рдбреАрдХреЗ рд╕реНрдерд╛рдкрд┐рдд
- Intel INDE рдореАрдбрд┐рдпрд╛ рдкреИрдХ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛
- Apache Ant (Android рдХреЗ рд▓рд┐рдП рдпреВрдирд┐рдЯреА рдкреНрд▓рдЧрдЗрди рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП)
рдкрд░рд┐рдпреЛрдЬрдирд╛ рдирд┐рд░реНрдорд╛рдг
рдПрдХрддрд╛ рд╕рдВрдкрд╛рджрдХ рдЦреЛрд▓реЗрдВ рдФрд░ рдПрдХ рдирдпрд╛ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдВред рд╕рдВрдкрддреНрддрд┐ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ, рдкреНрд▓рдЧрдЗрдиреНрд╕ рдлрд╝реЛрд▓реНрдбрд░ рдмрдирд╛рдПрдВ, рдФрд░ рдЗрд╕рдореЗрдВ рдПрдВрдбреНрд░реЙрдЗрдб рдлрд╝реЛрд▓реНрдбрд░ред
рдЬрд┐рд╕ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдПрдВрдбреНрд░реЙрдЗрдб рдХреЗ рд▓рд┐рдП Intel INDE рдореАрдбрд┐рдпрд╛ рдкреИрдХ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рд╡рд╣ рд▓рд┐рдмрд╛рд╕ рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рд╕реЗ, рдЖрдкрдХреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рдПрдВрдбреНрд░реЙрдЗрдб рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рджреЛ рдЬрд╛рд░ рдлрд╝рд╛рдЗрд▓реЛрдВ ( рдПрдВрдбреНрд░реЙрдЗрдб <<>> .jar рдФрд░ рдбреЛрдореЗрди- <version> .jar ) рдХреЛ рдХреЙрдкреА рдХрд░рддрд╛ рд╣реИред
рдЙрд╕реА Android рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ, Capturing.java рдирд╛рдордХ рдПрдХ рдирдИ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдВ рдФрд░ рдЙрд╕рдореЗрдВ рдирд┐рдореНрди рдХреЛрдб рдХреЙрдкреА рдХрд░реЗрдВ:
Capturing.java
package com.intel.inde.mp.samples.unity; import com.intel.inde.mp.android.graphics.FullFrameTexture; import android.os.Environment; import java.io.IOException; import java.io.File; public class Capturing { private static FullFrameTexture texture; public Capturing() { texture = new FullFrameTexture(); } // , public static String getDirectoryDCIM() { return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + File.separator; } // public void initCapturing(int width, int height, int frameRate, int bitRate) { VideoCapture.init(width, height, frameRate, bitRate); } // public void startCapturing(String videoPath) { VideoCapture capture = VideoCapture.getInstance(); synchronized (capture) { try { capture.start(videoPath); } catch (IOException e) { } } } // public void captureFrame(int textureID) { VideoCapture capture = VideoCapture.getInstance(); synchronized (capture) { capture.beginCaptureFrame(); texture.draw(textureID); capture.endCaptureFrame(); } } // public void stopCapturing() { VideoCapture capture = VideoCapture.getInstance(); synchronized (capture) { if (capture.isStarted()) { capture.stop(); } } } }
рдПрдХ рдФрд░ рдЬрд╛рд╡рд╛ рдлрд╝рд╛рдЗрд▓ рдЬреЛрдбрд╝реЗрдВ, рдЗрд╕ рдмрд╛рд░ VideoCapture.java рдирд╛рдо рдХреЗ рд╕рд╛рде:
VideoCapture.java
package com.intel.inde.mp.samples.unity; import com.intel.inde.mp.*; import com.intel.inde.mp.android.AndroidMediaObjectFactory; import com.intel.inde.mp.android.AudioFormatAndroid; import com.intel.inde.mp.android.VideoFormatAndroid; import java.io.IOException; public class VideoCapture { private static final String TAG = "VideoCapture"; private static final String Codec = "video/avc"; private static int IFrameInterval = 1; private static final Object syncObject = new Object(); private static volatile VideoCapture videoCapture; private static VideoFormat videoFormat; private static int videoWidth; private static int videoHeight; private GLCapture capturer; private boolean isConfigured; private boolean isStarted; private long framesCaptured; private VideoCapture() { } public static void init(int width, int height, int frameRate, int bitRate) { videoWidth = width; videoHeight = height; videoFormat = new VideoFormatAndroid(Codec, videoWidth, videoHeight); videoFormat.setVideoFrameRate(frameRate); videoFormat.setVideoBitRateInKBytes(bitRate); videoFormat.setVideoIFrameInterval(IFrameInterval); } public static VideoCapture getInstance() { if (videoCapture == null) { synchronized (syncObject) { if (videoCapture == null) { videoCapture = new VideoCapture(); } } } return videoCapture; } public void start(String videoPath) throws IOException { if (isStarted()) { throw new IllegalStateException(TAG + " already started!"); } capturer = new GLCapture(new AndroidMediaObjectFactory()); capturer.setTargetFile(videoPath); capturer.setTargetVideoFormat(videoFormat); AudioFormat audioFormat = new AudioFormatAndroid("audio/mp4a-latm", 44100, 2); capturer.setTargetAudioFormat(audioFormat); capturer.start(); isStarted = true; isConfigured = false; framesCaptured = 0; } public void stop() { if (!isStarted()) { throw new IllegalStateException(TAG + " not started or already stopped!"); } try { capturer.stop(); isStarted = false; } catch (Exception ex) { } capturer = null; isConfigured = false; } private void configure() { if (isConfigured()) { return; } try { capturer.setSurfaceSize(videoWidth, videoHeight); isConfigured = true; } catch (Exception ex) { } } public void beginCaptureFrame() { if (!isStarted()) { return; } configure(); if (!isConfigured()) { return; } capturer.beginCaptureFrame(); } public void endCaptureFrame() { if (!isStarted() || !isConfigured()) { return; } capturer.endCaptureFrame(); framesCaptured++; } public boolean isStarted() { return isStarted; } public boolean isConfigured() { return isConfigured; } }
рдорд╣рддреНрд╡рдкреВрд░реНрдг : рдкреИрдХреЗрдЬ рдирд╛рдо com.intel.inde.mp.samples.unity рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ ред рдпрд╣ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ ( рдкреНрд▓реЗрдпрд░ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ / рдЕрдиреНрдп рд╕реЗрдЯрд┐рдВрдЧреНрд╕ / рдмрдВрдбрд▓ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ ) рдореЗрдВ рдирд╛рдо рд╕реЗ рдореЗрд▓ рдЦрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдкрдХреЛ рдЬрд╛рд╡рд╛ рд╡рд░реНрдЧ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП C # рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ рдЙрд╕реА рдирд╛рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдпрджрд┐ рдпреЗ рд╕рднреА рдирд╛рдо рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХрд╛ рдЧреЗрдо рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдкрд░ рдХреНрд░реИрд╢ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред
рдЕрдкрдиреЗ рджреГрд╢реНрдп рдореЗрдВ рдХреБрдЫ рдЧрддрд┐рд╢реАрд▓ рд╕рд╛рдордЧреНрд░реА рдЬреЛрдбрд╝реЗрдВред рдЖрдк рдХрд┐рд╕реА рднреА рдореМрдЬреВрджрд╛ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд╕рд╛рде Android рдХреЗ рд▓рд┐рдП Intel INDE рдореАрдбрд┐рдпрд╛ рдкреИрдХ рдХреЛ рднреА рдПрдХреАрдХреГрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕реЗ рдЦрд░реЛрдВрдЪ рд╕реЗ рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рджреГрд╢реНрдп рдореЗрдВ рдХреБрдЫ рдЧрддрд┐рд╢реАрд▓ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВред рдЕрдиреНрдпрдерд╛, рдЖрдкрдХреЗ рд▓рд┐рдП рд╡реАрдбрд┐рдпреЛ рдХреНрд▓рд┐рдк рджреЗрдЦрдирд╛ рдмрд╣реБрдд рджрд┐рд▓рдЪрд╕реНрдк рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдЬрд┐рд╕рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИред
рдЕрдм, рдХрд┐рд╕реА рдЕрдиреНрдп Android рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА рддрд░рд╣, рд╣рдореЗрдВ рдореИрдирд┐рдлрд╝реЗрд╕реНрдЯ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред / рдкреНрд▓рдЧрдЗрдиреНрд╕ / рдПрдВрдбреНрд░реЙрдЗрдб рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ AndroidManifest.xml рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдВ рдФрд░ рдЗрд╕рдореЗрдВ рд╕рд╛рдордЧреНрд░реА рдХреЛ рдХреЙрдкреА рдХрд░реЗрдВ:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.intel.inde.mp.samples.unity" android:installLocation="preferExternal" android:theme="@android:style/Theme.NoTitleBar" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="18" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.INTERNET"/> <!тАФ --> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- OpenGL ES >= 2.0. --> <uses-feature android:glEsVersion="0x00020000" android:required="true"/> <application android:icon="@drawable/app_icon" android:label="@string/app_name" android:debuggable="true"> <activity android:name="com.unity3d.player.UnityPlayerNativeActivity" 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>
рд▓рд╛рдЗрди рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ:
package="com.intel.inde.mp.samples.unity"
рдкреИрдХреЗрдЬ рдХрд╛ рдирд╛рдо рдЖрдкрдХреЛ рдкрд╣рд▓реЗ рдмрддрд╛рдП рдЧрдП рд╕реЗ рдореЗрд▓ рдЦрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╡рд╣ рд╕рдм рдХреБрдЫ рд╣реИ рдЬреЛ рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдПред рдЪреВрдВрдХрд┐ рдПрдХрддрд╛ рдЕрдкрдиреЗ рдЬрд╛рд╡рд╛ рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рдЕрдкрдиреЗ рдЖрдк рд╕рдВрдХрд▓рд┐рдд рдирд╣реАрдВ рдХрд░ рдкрд╛рдПрдЧреА, рдЗрд╕рд▓рд┐рдП рд╣рдо рдПрдХ рдПрдВрдЯреА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдмрдирд╛рдПрдВрдЧреЗред
рдиреЛрдЯ : рдпрджрд┐ рдЖрдк рдЕрдиреНрдп рд╡рд░реНрдЧреЛрдВ рдФрд░ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдПрдВрдЯ-рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рддрджрдиреБрд╕рд╛рд░ рдмрджрд▓рдирд╛ рдЪрд╛рд╣рд┐рдП ( рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ)ред
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЪреАрдВрдЯреА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗрд╡рд▓ рдЗрд╕ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдХреЗ рд▓рд┐рдП рд╣реИред / рдкреНрд▓рдЧрдЗрдиреНрд╕ / Android / рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдПрдХ build.xml рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдБ:
build.xml
<?xml version="1.0" encoding="UTF-8"?> <project name="UnityCapturing"> <!-- Change this in order to match your configuration --> <property name="sdk.dir" value="C:\Android\sdk"/> <property name="target" value="android-18"/> <property name="unity.androidplayer.jarfile" value="C:\Program Files (x86)\Unity\Editor\Data\PlaybackEngines\androiddevelopmentplayer\bin\classes.jar"/> <!-- Source directory --> <property name="source.dir" value="\ProjectPath\Assets\Plugins\Android" /> <!-- Output directory for .class files--> <property name="output.dir" value="\ProjectPath\Assets\Plugins\Android\classes"/> <!-- Name of the jar to be created. Please note that the name should match the name of the class and the name placed in the AndroidManifest.xml--> <property name="output.jarfile" value="Capturing.jar"/> <!-- Creates the output directories if they don't exist yet. --> <target name="-dirs" depends="message"> <echo>Creating output directory: ${output.dir} </echo> <mkdir dir="${output.dir}" /> </target> <!-- Compiles this project's .java files into .class files. --> <target name="compile" depends="-dirs" description="Compiles project's .java files into .class files"> <javac encoding="ascii" target="1.6" debug="true" destdir="${output.dir}" verbose="${verbose}" includeantruntime="false"> <src path="${source.dir}" /> <classpath> <pathelement location="${sdk.dir}\platforms\${target}\android.jar"/> <pathelement location="${source.dir}\domain-1.0.903.jar"/> <pathelement location="${source.dir}\android-1.0.903.jar"/> <pathelement location="${unity.androidplayer.jarfile}"/> </classpath> </javac> </target> <target name="build-jar" depends="compile"> <zip zipfile="${output.jarfile}" basedir="${output.dir}" /> </target> <target name="clean-post-jar"> <echo>Removing post-build-jar-clean</echo> <delete dir="${output.dir}"/> </target> <target name="clean" description="Removes output files created by other targets."> <delete dir="${output.dir}" verbose="${verbose}" /> </target> <target name="message"> <echo>Android Ant Build for Unity Android Plugin</echo> <echo> message: Displays this message.</echo> <echo> clean: Removes output files created by other targets.</echo> <echo> compile: Compiles project's .java files into .class files.</echo> <echo> build-jar: Compiles project's .class files into .jar file.</echo> </target> </project>
рдкрде source.dir , output.dir рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ рдФрд░ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЖрдЙрдЯрдкреБрдЯ jar рдлрд╝рд╛рдЗрд▓ output.jarfile рдХрд╛ рдирд╛рдоред
рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдореЛрдб рдореЗрдВ, рдкреНрд░реЛрдЬреЗрдХреНрдЯ / рдкреНрд▓рдЧрдЗрдиреНрд╕ / рдПрдВрдбреНрд░реЙрдЗрдб рдлрд╝реЛрд▓реНрдбрд░ рдкрд░ рдЬрд╛рдПрдВ рдФрд░ рдкреНрд▓рдЧрдЗрди рдмрд┐рд▓реНрдб рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╢реБрд░реВ рдХрд░реЗрдВ
ant build-jar clean-post-jar
рдпрджрд┐ рдЖрдкрдиреЗ рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдм рдХреБрдЫ рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдХреБрдЫ рд╕реЗрдХрдВрдб рдХреЗ рдмрд╛рдж рдЖрдкрдХреЛ рдПрдХ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдЧрд╛, рдЬрд┐рд╕рдореЗрдВ рдХрд╣рд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рд╡рд┐рдзрд╛рдирд╕рднрд╛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкреВрд░реА рд╣реБрдИ!
рдлрд╝реЛрд▓реНрдбрд░ рдХреЗ рдкреНрд░рд╡реЗрд╢ рджреНрд╡рд╛рд░ рдкрд░, рдПрдХ рдирдИ рдХреИрдкреНрдЪрд░рд┐рдВрдЧ.рдЬрд░ рдлрд╝рд╛рдЗрд▓ рд╣рдорд╛рд░реЗ рдкреНрд▓рдЧрдЗрди рдХреЗ рдХреЛрдб рд╕реЗ рдпреБрдХреНрдд рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред
рдкреНрд▓рдЧрдЗрди рддреИрдпрд╛рд░ рд╣реИ, рдпрд╣ рдпреВрдирд┐рдЯреА 3 рдбреА рдХреЛрдб рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИ, рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рд╣рдо рдпреВрдирд┐рдЯреА рдФрд░ рд╣рдорд╛рд░реЗ рдПрдВрдбреНрд░реЙрдЗрдб рдкреНрд▓рдЧрдЗрди рдХреЛ рдЬреЛрдбрд╝рдиреЗ рд╡рд╛рд▓рд╛ рдПрдХ рдЖрд╡рд░рдг рдмрдирд╛рдПрдВрдЧреЗред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдХреИрдкреНрдЪрд░.рдПрдХреНрд╕ рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдБ
Capture.cs
using UnityEngine; using System.Collections; using System.IO; using System; [RequireComponent(typeof(Camera))] public class Capture : MonoBehaviour { public int videoWidth = 720; public int videoHeight = 1094; public int videoFrameRate = 30; public int videoBitRate = 3000; private string videoDir; public string fileName = "game_capturing-"; private float nextCapture = 0.0f; public bool inProgress { get; private set; } private static IntPtr constructorMethodID = IntPtr.Zero; private static IntPtr initCapturingMethodID = IntPtr.Zero; private static IntPtr startCapturingMethodID = IntPtr.Zero; private static IntPtr captureFrameMethodID = IntPtr.Zero; private static IntPtr stopCapturingMethodID = IntPtr.Zero; private static IntPtr getDirectoryDCIMMethodID = IntPtr.Zero; private IntPtr capturingObject = IntPtr.Zero; void Start() { if(!Application.isEditor) { // IntPtr classID = AndroidJNI.FindClass("com/intel/inde/mp/samples/unity/Capturing"); // constructorMethodID = AndroidJNI.GetMethodID(classID, "<init>", "()V"); // , initCapturingMethodID = AndroidJNI.GetMethodID(classID, "initCapturing", "(IIII)V"); startCapturingMethodID = AndroidJNI.GetMethodID(classID, "startCapturing", "(Ljava/lang/String;)V"); captureFrameMethodID = AndroidJNI.GetMethodID(classID, "captureFrame", "(I)V"); stopCapturingMethodID = AndroidJNI.GetMethodID(classID, "stopCapturing", "()V"); getDirectoryDCIMMethodID = AndroidJNI.GetStaticMethodID(classID, "getDirectoryDCIM", "()Ljava/lang/String;"); jvalue[] args = new jvalue[0]; videoDir = AndroidJNI.CallStaticStringMethod(classID, getDirectoryDCIMMethodID, args); // IntPtr local_capturingObject = AndroidJNI.NewObject(classID, constructorMethodID, args); if (local_capturingObject == IntPtr.Zero) { Debug.LogError("Can't create Capturing object"); return; } // capturingObject = AndroidJNI.NewGlobalRef(local_capturingObject); AndroidJNI.DeleteLocalRef(local_capturingObject); AndroidJNI.DeleteLocalRef(classID); } inProgress = false; nextCapture = Time.time; } void OnRenderImage(RenderTexture src, RenderTexture dest) { if (inProgress && Time.time > nextCapture) { CaptureFrame(src.GetNativeTextureID()); nextCapture += 1.0f / videoFrameRate; } Graphics.Blit(src, dest); } public void StartCapturing() { if (capturingObject == IntPtr.Zero) { return; } jvalue[] videoParameters = new jvalue[4]; videoParameters[0].i = videoWidth; videoParameters[1].i = videoHeight; videoParameters[2].i = videoFrameRate; videoParameters[3].i = videoBitRate; AndroidJNI.CallVoidMethod(capturingObject, initCapturingMethodID, videoParameters); DateTime date = DateTime.Now; string fullFileName = fileName + date.ToString("ddMMyy-hhmmss.fff") + ".mp4"; jvalue[] args = new jvalue[1]; args[0].l = AndroidJNI.NewStringUTF(videoDir + fullFileName); AndroidJNI.CallVoidMethod(capturingObject, startCapturingMethodID, args); inProgress = true; } private void CaptureFrame(int textureID) { if (capturingObject == IntPtr.Zero) { return; } jvalue[] args = new jvalue[1]; args[0].i = textureID; AndroidJNI.CallVoidMethod(capturingObject, captureFrameMethodID, args); } public void StopCapturing() { inProgress = false; if (capturingObject == IntPtr.Zero) { return; } jvalue[] args = new jvalue[0]; AndroidJNI.CallVoidMethod(capturingObject, stopCapturingMethodID, args); } }
рдЗрд╕ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдореБрдЦреНрдп рдХреИрдорд░реЗ рдкрд░ рдЕрд╕рд╛рдЗрди рдХрд░реЗрдВред рд╡реАрдбрд┐рдпреЛ рдХреИрдкреНрдЪрд░ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ рд╡реАрдбрд┐рдпреЛ рдкреНрд░рд╛рд░реВрдк рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЖрдк рдЙрдкрдпреБрдХреНрдд рдкреИрд░рд╛рдореАрдЯрд░ (рд╡реАрдбрд┐рдпреЛрд╡рд┐рдб, рд╡реАрдбрд┐рдпреЛрд╣рд╛рдЗрдЯ, рдЖрджрд┐) рдХреЛ рдмрджрд▓рдХрд░ рд╕реАрдзреЗ рд╕рдВрдкрд╛рджрдХ рдореЗрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдкреНрд░рд╛рд░рдВрдн () , StartCapturing () рдФрд░ StopCapturing () рд╡рд┐рдзрд┐рдпрд╛рдБ рдХрд╛рдлреА рддреБрдЪреНрдЫ рд╣реИрдВ рдФрд░ рдПрдХрддрд╛ рд╕реЗ рдкреНрд▓рдЧрдЗрди рдХреЛрдб рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд░рдг рд╣реИрдВред
рдЕрдзрд┐рдХ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ OnRenderImage () рд╡рд┐рдзрд┐ред рд╕реНрдХреНрд░реАрди рдкрд░ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрдиреЗ рд╕реЗ рдареАрдХ рдкрд╣рд▓реЗ рд╕рднреА рд░реЗрдВрдбрд░рд┐рдВрдЧ рдкреВрд░реА рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдЗрд╕реЗ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрдирдкреБрдЯ рдЫрд╡рд┐ src рдмрдирд╛рд╡рдЯ рдореЗрдВ рдирд┐рд╣рд┐рдд рд╣реИ, рд╣рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдмрдирд╛рд╡рдЯ рдореЗрдВ рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдпрд╣ рддрдВрддреНрд░ рдЖрдкрдХреЛ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рднрд╛рд╡реЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реБрдП рдЕрдВрддрд┐рдо рддрд╕реНрд╡реАрд░ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╣рдорд╛рд░реЗ рд╣рд┐рддреЛрдВ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдмрд╛рд╣рд░ рд╣реИ, рд╣рдо рдЪрд┐рддреНрд░ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВред рд╡реАрдбрд┐рдпреЛ рдкрд░ рдХрдмреНрдЬрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рд╡реАрдбрд┐рдпреЛ рдореЗрдВ рдЕрдВрддрд┐рдо рдЫрд╡рд┐ рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдХреИрдкреНрдЪрд░рд┐рдВрдЧ рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдХреИрдкреНрдЪрд░рдлреНрд░реЗрдо () рдХреЙрд▓ рдХрд░рдХреЗ рдФрд░ рдмрдирд╛рд╡рдЯ рдЖрдИрдбреА рдХреЛ рдЗрдирдкреБрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд╕ рдХрд░рдХреЗ рдмрдирд╛рд╡рдЯ рдЖрдИрдбреА рдХреЛ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред
рд╕реНрдХреНрд░реАрди рдкрд░ рдЖрдХрд░реНрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ src рдХреЛ рдирд┐рдпрдд рдХреЙрдкреА рдХрд░реЗрдВ :
Graphics.Blit(src, dest);
рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рдПрдХ рдмрдЯрди рдмрдирд╛рдПрдВ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд╣рдо рдЧреЗрдо рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╕реЗ рд╡реАрдбрд┐рдпреЛ рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рдХреЛ рдЕрдХреНрд╖рдо рдХрд░ рд╕рдХреЗрдВрдЧреЗред
рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, GUI рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдВ рдФрд░ рдЗрд╕реЗ рд╣реИрдВрдбрд▓рд░ рдЕрд╕рд╛рдЗрди рдХрд░реЗрдВред рд╣реИрдВрдбрд▓рд░ рдХреИрдкреНрдЪрд░рдпреВрдЬреА.рдЖрдИрдПрд╕рд╕реА рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕реНрдерд┐рдд рд╣реЛрдЧрд╛
CaptureGUI.cs
using UnityEngine; using System.Collections; public class CaptureGUI : MonoBehaviour { public Capture capture; private GUIStyle style = new GUIStyle(); void Start() { style.fontSize = 48; style.alignment = TextAnchor.MiddleCenter; } void OnGUI() { style.normal.textColor = capture.inProgress ? Color.red : Color.green; if (GUI.Button(new Rect(10, 200, 350, 100), capture.inProgress ? "[Stop Recording]" : "[Start Recording]", style)) { if (capture.inProgress) { capture.StopCapturing(); } else { capture.StartCapturing(); } } } }
рдХреИрдкреНрдЪрд░ рдХреНрд▓рд╛рд╕ рдХреА рдПрдХ рдЖрд╡реГрддреНрддрд┐ рдХреЗ рд╕рд╛рде рдХреИрдкреНрдЪрд░ рдлрд╝реАрд▓реНрдб рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рдирд╛ рдпрд╛рдж рд░рдЦреЗрдВред
рдЬрдм рдЖрдк рдХрд┐рд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╡реАрдбрд┐рдпреЛ рдХреИрдкреНрдЪрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╢реБрд░реВ рд╣реЛ рдЬрд╛рдПрдЧреА рдФрд░ рдмрдВрдж рд╣реЛ рдЬрд╛рдПрдЧреА, рдкрд░рд┐рдгрд╛рдо / mnt / sdcard / DCIM / рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд╕рд╣реЗрдЬрд╛ рдЬрд╛рдПрдЧрд╛ред
рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рдХрд╣рд╛ рдерд╛, рдпрд╣ рд╡рд┐рдзрд┐ рдХреЗрд╡рд▓ рдкреНрд░реЛ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдХрд╛рдо рдХрд░реЗрдЧреА (рдЖрдк рдирд┐: рд╢реБрд▓реНрдХ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдСрдирд░реЗрдВрдбрд░рдЗрдореЗрдЬ () рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЧреНрд░рд╛рдлрд┐рдХреНрд╕.рдмрд┐рд▓реНрдЯ рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ), рдПрдХ рдЕрдиреНрдп рд╡рд┐рд╢реЗрд╖рддрд╛ - рдЕрдВрддрд┐рдо рд╡реАрдбрд┐рдпреЛ рдореЗрдВ рдПрдХрддрд╛ рдЬреАрдпреВрдЖрдИ рдСрдмреНрдЬреЗрдХреНрдЯ рдирд╣реАрдВ рд╣реЛрдВрдЧреЗред рдЗрди рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдХреЛ рдирдВрдмрд░ рджреЛ рд╡рд┐рдзрд┐ рджреНрд╡рд╛рд░рд╛ рд╕рдорд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рдлрд╝реНрд░реЗрдордмрдлрд╝рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗред
рдлрд╝реНрд░реЗрдо рдмрдлрд╝рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡реАрдбрд┐рдпреЛ рдХреИрдкреНрдЪрд░ рдХрд░реЗрдВ
рд╣рдо Capturing.java рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░реЗрдВрдЧреЗ, рдЗрд╕рдХреЗ рд▓рд┐рдП рдмрд╕ рдЗрд╕рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдмрджрд▓реЗрдВ
Capturing.java
package com.intel.inde.mp.samples.unity; import com.intel.inde.mp.android.graphics.FullFrameTexture; import com.intel.inde.mp.android.graphics.FrameBuffer; import android.os.Environment; import java.io.IOException; import java.io.File; public class Capturing { private static FullFrameTexture texture; private FrameBuffer frameBuffer; public Capturing(int width, int height) { frameBuffer = new FrameBuffer(); frameBuffer.create(width, height); texture = new FullFrameTexture(); } public static String getDirectoryDCIM() { return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + File.separator; } public void initCapturing(int width, int height, int frameRate, int bitRate) { VideoCapture.init(width, height, frameRate, bitRate); } public void startCapturing(String videoPath) { VideoCapture capture = VideoCapture.getInstance(); synchronized (capture) { try { capture.start(videoPath); } catch (IOException e) { } } } public void beginCaptureFrame() { frameBuffer.bind(); } public void captureFrame(int textureID) { VideoCapture capture = VideoCapture.getInstance(); synchronized (capture) { capture.beginCaptureFrame(); texture.draw(textureID); capture.endCaptureFrame(); } } public void endCaptureFrame() { frameBuffer.unbind(); int textureID = frameBuffer.getTexture(); captureFrame(textureID); texture.draw(textureID); } public void stopCapturing() { VideoCapture capture = VideoCapture.getInstance(); synchronized (capture) { if (capture.isStarted()) { capture.stop(); } } } }
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдмрд╣реБрдд рд╕рд╛рд░реЗ рдмрджрд▓рд╛рд╡ рдирд╣реАрдВ рд╣реИрдВред рдореБрдЦреНрдп рдПрдХ рдирдИ рд╕реБрд╡рд┐рдзрд╛ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рд╣реИ
FrameBuffer frameBuffer;
рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛ рдЕрдм рдлреНрд░реЗрдо рдХреА рдЪреМрдбрд╝рд╛рдИ рдФрд░ рдКрдВрдЪрд╛рдИ рдХреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдЖрдХрд╛рд░ рдХреЗ рдлрд╝реНрд░реЗрдордмрдлрд╝рд░ рдХреЛ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рддреАрди рдирдП рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рддрд░реАрдХреЗ рд╕рд╛рдордиреЗ рдЖрдП рд╣реИрдВ: рдлрд╝реНрд░реЗрдордмрдлрд╝рд░рдЯреЗрдХреНрд╕реНрдЯреНрдпреЛрд░ () , рд╢реБрд░реБрдЖрддреА рдХреИрдЪрд░рдлреНрд░реЗрдо () рдФрд░ рдПрдВрдбрдХреИрдкреНрдЯреНрдпреЛрд░рдлреНрд░реЗрдо () ред рдЬрдм рд╣рдо C # рдореЗрдВ рдХреЛрдб рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗ рддреЛ рдЙрдирдХрд╛ рдЕрд░реНрде рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред
рд╣рдо VideoCapture.java рдлрд╝рд╛рдЗрд▓ рдХреЛ рдЕрдкрд░рд┐рд╡рд░реНрддрд┐рдд рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВред
рдЕрдЧрд▓рд╛, рдЖрдкрдХреЛ рдПрдВрдбреНрд░реЙрдЗрдб рдкреНрд▓рдЧ-рдЗрди рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдпрд╣ рдХреИрд╕реЗ рдХрд░рдирд╛ рд╣реИ, рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣рдордиреЗ рдКрдкрд░ рдЪрд░реНрдЪрд╛ рдХреА рд╣реИред
рдЕрдм рд╣рдо рдПрдХрддрд╛ рдореЗрдВ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред Capture.cs рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЦреЛрд▓реЗрдВ рдФрд░ рдЗрд╕рдХреА рд╕рд╛рдордЧреНрд░реА рдмрджрд▓реЗрдВ:
Capture.cs
using UnityEngine; using System.Collections; using System.IO; using System; [RequireComponent(typeof(Camera))] public class Capture : MonoBehaviour { public int videoWidth = 720; public int videoHeight = 1094; public int videoFrameRate = 30; public int videoBitRate = 3000; private string videoDir; public string fileName = "game_capturing-"; private float nextCapture = 0.0f; public bool inProgress { get; private set; } private bool finalizeFrame = false; private Texture2D texture = null; private static IntPtr constructorMethodID = IntPtr.Zero; private static IntPtr initCapturingMethodID = IntPtr.Zero; private static IntPtr startCapturingMethodID = IntPtr.Zero; private static IntPtr beginCaptureFrameMethodID = IntPtr.Zero; private static IntPtr endCaptureFrameMethodID = IntPtr.Zero; private static IntPtr stopCapturingMethodID = IntPtr.Zero; private static IntPtr getDirectoryDCIMMethodID = IntPtr.Zero; private IntPtr capturingObject = IntPtr.Zero; void Start() { if (!Application.isEditor) { // IntPtr classID = AndroidJNI.FindClass("com/intel/inde/mp/samples/unity/Capturing "); // constructorMethodID = AndroidJNI.GetMethodID(classID, "<init>", "(II)V"); // , initCapturingMethodID = AndroidJNI.GetMethodID(classID, "initCapturing", "(IIII)V"); startCapturingMethodID = AndroidJNI.GetMethodID(classID, "startCapturing", "(Ljava/lang/String;)V"); beginCaptureFrameMethodID = AndroidJNI.GetMethodID(classID, "beginCaptureFrame", "()V"); endCaptureFrameMethodID = AndroidJNI.GetMethodID(classID, "endCaptureFrame", "()V"); stopCapturingMethodID = AndroidJNI.GetMethodID(classID, "stopCapturing", "()V"); getDirectoryDCIMMethodID = AndroidJNI.GetStaticMethodID(classID, "getDirectoryDCIM", "()Ljava/lang/String;"); jvalue[] args = new jvalue[0]; videoDir = AndroidJNI.CallStaticStringMethod(classID, getDirectoryDCIMMethodID, args); // jvalue[] constructorParameters = new jvalue[2]; constructorParameters[0].i = Screen.width; constructorParameters[1].i = Screen.height; IntPtr local_capturingObject = AndroidJNI.NewObject(classID, constructorMethodID, constructorParameters); if (local_capturingObject == IntPtr.Zero) { Debug.LogError("Can't create Capturing object"); return; } // capturingObject = AndroidJNI.NewGlobalRef(local_capturingObject); AndroidJNI.DeleteLocalRef(local_capturingObject); AndroidJNI.DeleteLocalRef(classID); } inProgress = false; nextCapture = Time.time; } void OnPreRender() { if (inProgress && Time.time > nextCapture) { finalizeFrame = true; nextCapture += 1.0f / videoFrameRate; BeginCaptureFrame(); } } public IEnumerator OnPostRender() { if (finalizeFrame) { finalizeFrame = false; yield return new WaitForEndOfFrame(); EndCaptureFrame(); } else { yield return null; } } public void StartCapturing() { if (capturingObject == IntPtr.Zero) { return; } jvalue[] videoParameters = new jvalue[4]; videoParameters[0].i = videoWidth; videoParameters[1].i = videoHeight; videoParameters[2].i = videoFrameRate; videoParameters[3].i = videoBitRate; AndroidJNI.CallVoidMethod(capturingObject, initCapturingMethodID, videoParameters); DateTime date = DateTime.Now; string fullFileName = fileName + date.ToString("ddMMyy-hhmmss.fff") + ".mp4"; jvalue[] args = new jvalue[1]; args[0].l = AndroidJNI.NewStringUTF(videoDir + fullFileName); AndroidJNI.CallVoidMethod(capturingObject, startCapturingMethodID, args); inProgress = true; } private void BeginCaptureFrame() { if (capturingObject == IntPtr.Zero) { return; } jvalue[] args = new jvalue[0]; AndroidJNI.CallVoidMethod(capturingObject, beginCaptureFrameMethodID, args); } private void EndCaptureFrame() { if (capturingObject == IntPtr.Zero) { return; } jvalue[] args = new jvalue[0]; AndroidJNI.CallVoidMethod(capturingObject, endCaptureFrameMethodID, args); } public void StopCapturing() { inProgress = false; if (capturingObject == IntPtr.Zero) { return; } jvalue[] args = new jvalue[0]; AndroidJNI.CallVoidMethod(capturingObject, stopCapturingMethodID, args); } }
рдЗрд╕ рдХреЛрдб рдореЗрдВ, рд╣рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдмрджрд▓рд╛рд╡ рдорд┐рд▓реЗ, рд▓реЗрдХрд┐рди рдХрд╛рдо рдХрд╛ рддрд░реНрдХ рд╕рд░рд▓ рд░рд╣рд╛ред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдХреИрдкреНрдЪрд░рд┐рдВрдЧ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдлреНрд░реЗрдо рдЖрдпрд╛рдо рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред рдирдП рдирд┐рд░реНрдорд╛рддрд╛ рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ - (II) рд╡реАред рдЬрд╛рд╡рд╛ рдкрдХреНрд╖ рдкрд░, рд╣рдо рдПрдХ рдлрд╝реНрд░реЗрдордмрдлрд╝рд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдкреИрд░рд╛рдореАрдЯрд░ рдкрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред
OnPreRender () рд╡рд┐рдзрд┐ рдХреЛ рдЙрд╕ рджреГрд╢реНрдп рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдХреИрдорд░рд╛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдВ рд╣рдо рдЕрдкрдиреЗ рдлрд╝реНрд░реЗрдордмрдлрд╝рд░ рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╕рднреА рдкреНрд░рддрд┐рдкрд╛рджрди FrameBuffer рдХреЛ рд╕реМрдВрдкреА рдЧрдИ рдмрдирд╛рд╡рдЯ рдкрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
OnPostRender () рдкрджреНрдзрддрд┐ рдХреЛ рдкреВрд░реНрдг рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рдо рдлрд╝реНрд░реЗрдо рдХреЗ рдЕрдВрдд рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рддреЗ рд╣реИрдВ, рдлрд╝реНрд░реЗрдордмрдлрд╝рд░ рдХреЛ рдмрдВрдж рдХрд░ рджреЗрддреЗ рд╣реИрдВ рдФрд░ рдореАрдбрд┐рдпрд╛ рдкреИрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕реНрдХреНрд░реАрди рдкрд░ рд╕реАрдзреЗ рдмрдирд╛рд╡рдЯ рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдмрдирд╛рддреЗ рд╣реИрдВ (рджреЗрдЦреЗрдВ CaptCureureFrame () рдХреИрдкреНрдЪрд░рд┐рдВрдЧ рдХреА рд╡рд┐рдзрд┐ред рдЬрд╛рд╡рд╛ рд╡рд░реНрдЧ)ред
рдЙрддреНрдкрд╛рджрдХрддрд╛
рдЕрдХреНрд╕рд░, рдбреЗрд╡рд▓рдкрд░реНрд╕ рдкреВрдЫрддреЗ рд╣реИрдВ рдХрд┐ рд╡реАрдбрд┐рдпреЛ рдХреИрдкреНрдЪрд░ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдХрд┐рддрдирд╛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдПрдлрдкреАрдПрд╕ "рдирд╛рд▓реА" рдХреИрд╕реЗ рдХрд░реЗрдЧрд╛ред рдкрд░рд┐рдгрд╛рдо рд╣рдореЗрд╢рд╛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди, рджреГрд╢реНрдп рдХреА рдЬрдЯрд┐рд▓рддрд╛ рдФрд░ рдбрд┐рд╡рд╛рдЗрд╕ рдЬрд┐рд╕ рдкрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЪрд▓ рд░рд╣рд╛ рд╣реИ, рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред
рддрд╛рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдкреНрд░рджрд░реНрд╢рди рдЙрдкрдХрд░рдг рд╣реЛ, рдЪрд▓реЛ рдПрдХ рд╕рд░рд▓ рдПрдлрдкреАрдПрд╕ рдХрд╛рдЙрдВрдЯрд░ рдЬреЛрдбрд╝реЗрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рджреГрд╢реНрдп рдореЗрдВ рдПрдХ рдПрдХрддрд╛ GUI рдСрдмреНрдЬреЗрдХреНрдЯ рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдЗрд╕реЗ рдирд┐рдореНрди рдХреЛрдб рдЕрд╕рд╛рдЗрди рдХрд░реЗрдВ:
FPS.cs
using UnityEngine; using System.Collections; public class FPSCounter : MonoBehaviour { public float updateRate = 4.0f; // 4 updates per sec. private int frameCount = 0; private float nextUpdate = 0.0f; private float fps = 0.0f; private GUIStyle style = new GUIStyle(); void Start() { style.fontSize = 48; style.normal.textColor = Color.white; nextUpdate = Time.time; } void Update() { frameCount++; if (Time.time > nextUpdate) { nextUpdate += 1.0f / updateRate; fps = frameCount * updateRate; frameCount = 0; } } void OnGUI() { GUI.Label(new Rect(10, 110, 300, 100), "FPS: " + fps, style); } }
рдЗрд╕ рдкрд░, рд╣рдо рдЕрдкрдиреЗ рдХрд╛рдо рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдкреНрд░рдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдпреВрдирд┐рдЯреА 3 рдбреА рдХреЗ рд╕рд╛рде рдПрдХреАрдХрд░рдг рдпрд╛ рдЗрдВрдЯреЗрд▓ рдЖрдИрдПрдирдбреАрдИ рдореАрдбрд┐рдпрд╛ рдкреИрдХ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреЛрдИ рд╕рд╡рд╛рд▓ рд╣реИ, рддреЛ рд╣рдо рдЙрдиреНрд╣реЗрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдЬрд╡рд╛рдм рджреЗрдВрдЧреЗред