几天前下载到一个安卓工程,可以把图片合成视频,突然想开坑做一个Unity录屏功能,然后就开始了。

Android代码:

package cn.net.xuefei.unityrec;import static com.googlecode.javacv.cpp.opencv_highgui.cvLoadImage;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;import com.googlecode.javacv.FFmpegFrameRecorder;
import com.googlecode.javacv.FrameRecorder.Exception;
import com.googlecode.javacv.cpp.opencv_core;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;public class MainActivity extends UnityPlayerActivity {private static MainActivity ma;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);ma = this;}public static void StartFusionVideo(final String videoName, final String frameCount, final String vidoeLength) {ma.runOnUiThread(new Runnable() {public void run() { //if (!isStarted()) {int fc = Integer.parseInt(frameCount);long vl = Long.parseLong(vidoeLength);start(videoName, fc, vl);}}});}public static void PauseFusionVideo() {pause();}public static void StopFusionVideo() {stop();}private static int switcher = 0;// 录像键private static boolean isPaused = false;// 暂停键private static String filename = null;public static int INDEX_MAX = 21;private static String filePathRoot = Environment.getExternalStorageDirectory()+ "/Android/data/cn.net.xuefei.unityrec/files/";private static Bitmap frame;private static Bitmap testBitmap;public static void start(final String videoName, final int frameCount, final long vidoeLength) {Log.e("start参数:", "videoName:" + videoName + " frameCount:" + frameCount + " vidoeLength:" + vidoeLength);INDEX_MAX = frameCount - 1;frame = Bitmap.createBitmap(1080, 1920, Bitmap.Config.RGB_565);testBitmap = Bitmap.createBitmap(1080, 1920, Bitmap.Config.RGB_565);switcher = 1;new Thread() {public void run() {OutputStream os = null;filename = videoName + ".mp4";testBitmap = getFrameBitmap(filePathRoot + "0.jpg");FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(filePathRoot + filename, 1080, 1920);recorder.setFormat("mp4");// recorder.setFrameRate(30f);//录像帧率Log.e("录像帧率 ", (frameCount / (vidoeLength / 1000)) + "");Log.e("录像时长 ", vidoeLength + "");Log.e("frameCount", frameCount + "");recorder.setFrameRate(frameCount / (vidoeLength / 1000));// 录像帧率// recorder.setTimestamp(vidoeLength);try {recorder.start();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}int index = 0;while (switcher != 0) {if (!isPaused) {File file = new File(filePathRoot + "video.jpg");if (!file.exists()) {file.getParentFile().mkdirs();try {file.createNewFile();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}} else {file = new File(filePathRoot + "video.jpg");}try {os = new FileOutputStream(file);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}frame = getFrameBitmap(filePathRoot + index + ".jpg");frame.compress(Bitmap.CompressFormat.JPEG, 100, os);try {os.flush();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}try {os.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}// frame.recycle();// frame = null;opencv_core.IplImage image = cvLoadImage(filePathRoot + "video.jpg");try {recorder.record(image);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (index + 1 > INDEX_MAX) {// index = 1;try {recorder.stop();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}UnityPlayer.UnitySendMessage("UnityREC", "FusionOver", videoName);} else {index++;}try {recorder.stop();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}UnityPlayer.UnitySendMessage("UnityREC", "FusionOver", videoName);}}}.start();}public static void stop() {switcher = 0;isPaused = false;}public static void pause() {if (switcher == 1) {isPaused = true;}}public static void restart() {if (switcher == 1) {isPaused = false;}}public static boolean isStarted() {if (switcher == 1) {return true;} else {return false;}}public static boolean isPaused() {return isPaused;}static Bitmap image = null;private static Bitmap getFrameBitmap(String filename) {image = BitmapFactory.decodeFile(filename);return image;}
}

Unity代码:

using UnityEngine;
using System.Collections;
using System.IO;
using System;
using System.Diagnostics;
using System.Collections.Generic;public class UnityREC : MonoBehaviour
{Texture2D tex;int width;int height;Queue<byte[]> imageBytes = new Queue<byte[]>();bool isREC = false;int index = 0;private Rect CutRect = new Rect(0, 0, 1, 1);private RenderTexture rt;// Use this for initializationvoid Start(){width = Screen.width;height = Screen.height;tex = new Texture2D(width, height, TextureFormat.RGB24, false);rt = new RenderTexture(width, height, 2, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default);Camera.main.pixelRect = new Rect(0, 0, width, height);Camera.main.targetTexture = rt;//StartCoroutine(StartREC());}// Update is called once per framevoid Update(){if (isREC && Time.time > nextFire){//StartCoroutine(StartREC());StartRec();}}float startTime = 0;float videoLength = 0;void OnGUI(){if (GUI.Button(new Rect(0, 0, 300, 300), "开始截屏")){if (isREC){isREC = false;videoLength = Time.time - startTime;return;}else{isREC = true;startTime = Time.time;index = 0;return;}}if (GUI.Button(new Rect(0, 300, 300, 300), "合成视频")){
#if UNITY_ANDROIDAndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");jo.CallStatic("StartFusionVideo", new object[] { DateTime.Now.ToFileTime().ToString(), index + "", Convert.ToInt32(videoLength * 1000).ToString() });
#elif  UNITY_IPHONE#endif}}void FixedUpdate(){if (imageBytes.Count > 0){File.WriteAllBytes(Application.persistentDataPath + "/" + index + ".jpg", imageBytes.Dequeue());index++;}}byte[] imagebytes;float fireRate = 0.02F;float nextFire = 0.0F;IEnumerator StartREC(){nextFire = Time.time + fireRate;yield return new WaitForEndOfFrame();tex.ReadPixels(new Rect(0, 0, width, height), 0, 0, false);//tex.Compress(false);//对屏幕缓存进行压缩 imagebytes = tex.EncodeToJPG(50);//转化为jpg图  //float t = Time.time;//Stopwatch sw = new Stopwatch();//sw.Start();//UnityEngine.Debug.Log(string.Format("total: {0} ms", Time.time - t));imageBytes.Enqueue(imagebytes);// sw.Stop();//UnityEngine.Debug.Log(string.Format("total: {0} ms", sw.ElapsedMilliseconds)); }void StartRec(){nextFire = Time.time + fireRate;float t = Time.time;Stopwatch sw = new Stopwatch();sw.Start();UnityEngine.Debug.Log(string.Format("total: {0} ms", Time.time - t));Camera.main.Render();RenderTexture.active = rt;tex.ReadPixels(new Rect(width * CutRect.x, width * CutRect.y, width * CutRect.width, height * CutRect.height), 0, 0);Camera.main.targetTexture = null;RenderTexture.active = null;imagebytes = tex.EncodeToJPG();imageBytes.Enqueue(imagebytes);sw.Stop();UnityEngine.Debug.Log(string.Format("total: {0} ms", sw.ElapsedMilliseconds));}public void FusionOver(string videoName){UnityEngine.Debug.Log("videoName:" + videoName);}}

现在的结果是,截图实现了,但是很卡……

卡到截取一帧耗时300多毫秒……

合成视频调用失败:

不知道万能的博友有什么建议……

点击这里下载工程

Unity录屏实现(一)相关推荐

  1. Unity录屏功能插件NatCorder使用简记

    Unity录屏功能插件NatCorder使用简记 简单介绍 插件下载 使用简介 代码 参考链接 简单介绍 NatCorder 是一个轻量级且易于使用的全功能视频录制 API,适用于 iOS.Andro ...

  2. Unity 录屏截屏到Android相册,支持鸿蒙

    Unity截屏保存到Android相册 Unity端截屏代码 Unity需要的Android Jar及Java代码(由于之前是找的一个Jar库因不支持鸿蒙所以自己动手二次开发的Java调用库) Uni ...

  3. Unity录屏插件Recorder

    Unity Recorder是一个编辑器中的录制工具(仅能用于编辑器中),可以在运行模式下将Unity场景及动画.Timeline录制成动画或视频. 相对于直接录屏有这么几点好处: 可以自定义输出分辨 ...

  4. Unity录屏实现(三)

    继续填上次的坑,,本文只是转载,偶尔看见一博客说 5.1有录屏api,好吧,还是看代码吧: Android代码: package cn.net.xuefei.unityrec; import java ...

  5. Unity录屏的坑(FFmpeg)

    一.FFmpeg 安装与Setup Screen Capturer Recorder v0.12.10安装 下载地址:链接:https://pan.baidu.com/s/1cIKyKMa6nhymV ...

  6. Unity实用小工具或脚本——录屏工具

    一.前言 本文要讲的录屏不是使用Unity自带的那个截屏方法,因为unity自带的都只能截取unity程序本身显示的画面内容,至于unity程序之外的内容,如电脑桌面上的其他的程序内容是无法录屏的.本 ...

  7. Unity IOS 录屏

    用到的是ios的replaykit,现在使用的unity 2017.1.f3版本已经自己集成了,所以调用相应提供的接口就可以,很简单 但是目前测试会在安装后第一次录屏的时候出现黑屏录屏失败的情况,所以 ...

  8. Recorder丨Unity官方录屏插件使用介绍

    一.利用TimeLine录屏 1.目标: 结合TimeLine,使用Unity Recorder进行录屏并导出视频. 2.操作方法: 1.应用商城导入插件 2.TimeLine左侧右键添加 Recor ...

  9. Unity官方录屏插件Unity Recorder的简单使用

    Unity官方录屏插件Unity Recorder的简单使用 插件简介 导入插件 利用TimeLine录屏 普通录屏 插件功能 参考链接 另 插件简介 Unity Recorder是一个编辑器中的录制 ...

最新文章

  1. 机器学习数学基础:常见分布与假设检验
  2. 搜索专题: HDU1428漫步校园
  3. 一些经典的常用ASP代码[经典简单] (2)
  4. Java 并发编程CyclicBarrier的应用与源码解析(基于ReentrantLock实现)
  5. Python笔记之两个二维列表构成的矩阵对应元素相减并遍历每个差值
  6. 吴恩达深度学习4.1练习_Convolutional Neural Networks_Convolution_model_Application_2
  7. SFR算法详解(二)——斜棱法
  8. Python大众点评店铺刷好评
  9. chm打开空白(chm打开空白)
  10. 阿里巴巴产品实习生23天
  11. 士兵突击:每个人的心灵史
  12. 亮剑精神--亮码精神
  13. php下lua的运行,phpStudy中起用lua脚本
  14. 中小学计算机教学大纲,中小学信息技术教材教法教学大纲.doc
  15. c语言记录键盘敲击次数,【转】你知道一天敲键盘的敲击次数能达到多少么
  16. EasyCVR新版本v2.6.0调用接口获取视频流的方法变更
  17. macOS Catalina 10.15.4(19E287)原版镜像 by OpenCore-0.5.8-04-07编译版
  18. Mac彻底卸载Paragon NTFS方法
  19. 人能不能向计算机一样输入知识,电视机能不能做为计算机的显示器来使用
  20. java与捷安特自行车哪个好_自行车品牌捷安特和美利达,哪个实力更强?你更喜欢买哪一品牌?...

热门文章

  1. 基于stm32、Android和Html的温湿度监控系统的设计
  2. zynq AXU2CG 转接板 原理图 对应引脚图
  3. 写给喜欢计算机的机械专业硕士生
  4. could和may区别请求_can和may的用法区别
  5. 摩拜进军澳大利亚;刘强东怒斥行业潜规则;博通计划1300亿美元收购高通丨价值早报
  6. SqlServer转换时间CONVERT
  7. 使用python随机画几何图形(矩形、圆形、三角形...)
  8. docker更改仓库地址(加速器到阿里,不访问外网)运行容器3
  9. 51单片机题目项目汇总 - 100例
  10. windows家长时长控制_如何在Windows 7上使用家长控制