精华内容
下载资源
问答
  • SCR Screen Recorder 》是目前支持设备类型最多且最稳定的一款屏幕录像工具。大多数同类屏幕录像工具都受限于硬件配置,中端机录制出来的视频基本都会卡顿或花屏。SCR Screen Recorder 对中端机的支持算比较友好,把...
  • 键盘记录保护 常见的Android键盘记录主要依靠读取/dev/...屏幕录像测试 即连续截屏,通过视觉反馈效果来窃听密码等敏感信息: adb shell /system/bin/screencap -p 安卓设备中的输出png路径 需要root。 scr...

    键盘记录保护

    常见的Android键盘记录主要依靠读取/dev/input/event0设备
    需要root。
    需要编写专门的Native测试工具
    键盘、触屏之类均能捕获到。
    也有通过注册输入法来窃听键盘的方法。

    在这里插入图片描述

    屏幕录像测试

    即连续截屏,通过视觉反馈效果来窃听密码等敏感信息:

    adb shell /system/bin/screencap -p 安卓设备中的输出png路径

    需要root。

    screencap输出到安卓设备中,不是输出到电脑中。

    注意: FLAG_SECURE会妨碍screencap,

    但对于root权限下直接读取屏幕缓存的方法是不起作用的,测试中不被认定为有效修复。

    在这里插入图片描述在这里插入图片描述

    展开全文
  • 屏幕录像DEMO

    2018-07-09 20:30:31
    录制屏幕的demo,适用于android app。录制屏幕的demo,适用于android app
  • 快速屏幕录像机 Quick Screen Recorder是Windows的轻型桌面屏幕记录器,建立在WinForms(C#)的基础上。 安装 Windows 7、8.1、10 | (2.3 MB)| 使用 产品特点 -以.avi格式进行屏幕录制-记录屏幕区域-多显示器支持...
  • 录制屏幕录像(来自屏幕的视频)-从屏幕/选项卡上录制视频(屏幕录像)(!); -录制来自其他活动程序的视频(!); -自定义您的屏幕分辨率和FPS; -您可以在视频上绘画; 编辑屏幕截图-将不同的图案和文本框粘贴...
  • :high_voltage: 电子屏幕录像机 使用适用于Mac,Linux和Windows的网络技术构建的桌面屏幕录像机应用程序 这个专案仅作学习用途,最初来自 YouTube频道,并有我自己的修改 下载 适用于Mac,Linux和Windows。 执照
  • 现在的安卓手机屏幕录像软件有很多,今天大眼仔给大家带来一款...Screen Recorder 5+ 作为一款轻量级的安卓手机屏幕录像软件,对于应用程序白热化的今天,或许 Screen Recorder 5+ 可以在你的手机 APP 中留有一席空间。
  • 极简录屏助手是一款专业的屏幕录像软件。支持声音、画面同步录制效果,可用于实现录制软件操作、教学演示、课件动画、游戏过程、视频聊天等各种需求, 录制时长无任何限制。在win10系统下,支持屏幕缩放的录屏操作。...
  • #功能: 屏幕录像 主界面: 主文件(Tl_C02.py) import sys import time import os from PyQt5.QtWidgets import * from PyQt5 import QtGui, QtCore, QtWidgets # from PyQt5.QtWidgets import QTab...

    # Time: 2020/06/16

    #Author: Xiaohong

    # 运行环境: OS: Windows 10

    #  Python: 3.7

    # 功能: 屏幕录像

    主界面:

    主文件(Tl_C02.py)

    import sys
    import time
    import os
    from PyQt5.QtWidgets import *
    from PyQt5 import QtGui, QtCore, QtWidgets
    # from PyQt5.QtWidgets import QTableWidget, QProgressBar, QLineEdit, QComboBox, QFrame, QTableWidgetItem
    from PyQt5.QtCore import *
    from PyQt5.QtGui import *
    # 这个test_pyqt是ui文件对应的py文件的文件名
    from Ui_qt_C02 import Ui_qt_c02
    
    from PIL import ImageGrab  # pip3 install pillow
    import numpy as np    # pip3 install numpy
    import cv2             # pip3 install opencv2
    import datetime
    from pynput import keyboard   # pip3 install pynput
    import threading
    
    flag = False  # 停止标志位
    
    # 调用 QT 设计的界面对应的类
    
    
    class WC02(QDialog):
        def __init__(self, parent=None):
            super(WC02, self).__init__(parent)
            self.child = Ui_qt_c02()
            self.child.setupUi(self)
            self.child.btn_start.clicked.connect(self.start_screen)
            self.child.btn_select.clicked.connect(self.sel_directory)
            self.child.btn_open_path.clicked.connect(self.open_path)
    
        # 设立函数,来取得当前时间
    
        def get_sysdate(self):
            now = time.strftime("%Y%m%d %H%M%S", time.localtime(time.time()))
            # print(now)
            return now
    
        def sel_directory(self):
            pass
            #     打开文件有以下3种:
            # 1、单个文件打开 QFileDialog.getOpenFileName()
            # 2、多个文件打开 QFileDialog.getOpenFileNames()
            # 3、打开文件夹 QFileDialog.getExistingDirectory()
            dir_path = QFileDialog.getExistingDirectory(self, "请选择文件夹路径", "/")
            # print(dir_path)
            self.child.t_directory.setText(dir_path)        
    
        def video_record(self):
            # """
            # 屏幕录制!
            # :return:
            # """
            name = self.get_sysdate()+'.avi'   #当前的时间
            t_directory = self.child.t_directory.text()   #新生成文件, 要保存的文件夹
            if t_directory == '':
                pass
            else:
                new_file_name = os.path.join(t_directory, name)   #新生成的文件,含路径
                # print(new_file_name)
    
                p = ImageGrab.grab()  # 获得当前屏幕
                a, b = p.size  # 获得当前屏幕的大小
                fourcc = cv2.VideoWriter_fourcc(*'XVID')  # 编码格式   常用的有 “DIVX"、”MJPG"、“XVID”、“X264"
                # 输出文件 帧率为16,可以自己设置
                # VideoWriter(filename, fourcc, fps, frameSize[, isColor]) -> <VideoWriter object>
                # 第一个参数是要保存的文件的路径
                # fourcc 指定编码器
                # fps 要保存的视频的帧率,本例为 20fps (frame per second)
                # frameSize 要保存的文件的画面尺寸,本例为 当前屏幕的大小
                # isColor 指示是黑白画面还是彩色的画面            
                video = cv2.VideoWriter(new_file_name, fourcc, 20, (a, b))
                while True:
                    im = ImageGrab.grab()
                    # CvtColor是Opencv里的 转换图像的颜色空间
                    # cvtColor(src, code, dst=None, dstCn=None)
                    # src: 原图像; code: 指定颜色空间转换类型;
                    # dst: 目标图像;与原图像大小深度一致;dstCn: 指定目标图像通道数;默认None,则会根据src、code自动计算;
                    # https://www.cnblogs.com/chenzhen0530/p/10741264.html 有说明
                    # 转为opencv的BGR格式
                    imm = cv2.cvtColor(np.array(im), cv2.COLOR_RGB2BGR)
                    video.write(imm)
                    if flag:
                        print("录制结束!")
                        break
                video.release()
    
        def on_press(self, key):
            # """
            # 键盘监听事件!!!
            # :param key:
            # :return:
            # """
            # print(key)
            global flag
            if key == keyboard.Key.esc:
                flag = True
                print("stop monitor!")
                return False  # 返回False,键盘监听结束!
    
        def start_screen(self):
            pass
            reply = QMessageBox.information(
                self, '提醒', '准备开始录制... 按ESC 结束录制', QMessageBox.Yes, QMessageBox.Yes)
            th = threading.Thread(target=self.video_record)
            th.start()
            with keyboard.Listener(on_press=self.on_press) as listener:
                listener.join()
            reply = QMessageBox.information(
                self, '提醒', '已录制完毕', QMessageBox.Yes, QMessageBox.Yes)
    
        def open_path(self):
            dir_path = self.child.t_directory.text()
            if os.path.exists(dir_path):
                os.startfile(dir_path)
            #     打开文件有以下3种:
            # 1、单个文件打开 QFileDialog.getOpenFileName()
            # 2、多个文件打开 QFileDialog.getOpenFileNames()
            # 3、打开文件夹 QFileDialog.getExistingDirectory()
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        myc02 = WC02()
        myc02.show()
        sys.exit(app.exec_())
    

    QT5 的界面设计(qt_C02.ui) 

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>qt_c02</class>
     <widget class="QDialog" name="qt_c02">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>726</width>
        <height>300</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>录屏软件</string>
      </property>
      <widget class="QPushButton" name="btn_start">
       <property name="geometry">
        <rect>
         <x>70</x>
         <y>70</y>
         <width>121</width>
         <height>23</height>
        </rect>
       </property>
       <property name="text">
        <string>开始录屏</string>
       </property>
      </widget>
      <widget class="QPushButton" name="btn_exit">
       <property name="geometry">
        <rect>
         <x>70</x>
         <y>150</y>
         <width>121</width>
         <height>23</height>
        </rect>
       </property>
       <property name="text">
        <string>关闭程序</string>
       </property>
      </widget>
      <widget class="QLineEdit" name="t_directory">
       <property name="geometry">
        <rect>
         <x>110</x>
         <y>20</y>
         <width>371</width>
         <height>20</height>
        </rect>
       </property>
      </widget>
      <widget class="QLabel" name="label_2">
       <property name="geometry">
        <rect>
         <x>30</x>
         <y>20</y>
         <width>71</width>
         <height>16</height>
        </rect>
       </property>
       <property name="text">
        <string>文件夹路径</string>
       </property>
      </widget>
      <widget class="QPushButton" name="btn_select">
       <property name="geometry">
        <rect>
         <x>480</x>
         <y>20</y>
         <width>31</width>
         <height>23</height>
        </rect>
       </property>
       <property name="text">
        <string>...</string>
       </property>
      </widget>
      <widget class="QPushButton" name="btn_open_path">
       <property name="geometry">
        <rect>
         <x>70</x>
         <y>110</y>
         <width>121</width>
         <height>23</height>
        </rect>
       </property>
       <property name="text">
        <string>打开下载目录</string>
       </property>
      </widget>
     </widget>
     <resources/>
     <connections>
      <connection>
       <sender>btn_exit</sender>
       <signal>clicked()</signal>
       <receiver>qt_c02</receiver>
       <slot>close()</slot>
       <hints>
        <hint type="sourcelabel">
         <x>115</x>
         <y>89</y>
        </hint>
        <hint type="destinationlabel">
         <x>296</x>
         <y>142</y>
        </hint>
       </hints>
      </connection>
     </connections>
    </ui>
    

     

    展开全文
  • 屏幕录像工具有好多?哪些支持M1电脑呢?别急,今天小编给大家整理了6款支持M1屏幕录像工具,每一个都有各自的特点,还在等什么,快来跟小编看看吧! 1.ScreenFlow for mac屏幕录像软件 Screenflow for mac是Mac ...

    屏幕录像工具有好多?哪些支持M1电脑呢?别急,今天小编给大家整理了6款支持M1屏幕录像工具,每一个都有各自的特点,还在等什么,快来跟小编看看吧!

    1.ScreenFlow for mac屏幕录像软件

    Screenflow for mac是Mac OS平台上一款优秀的屏幕录像软件。不但可以录制桌面操作还可以进行后期的剪辑工作,可以添加字幕, 增加视频效果与文字效果等功能,支持输出成MOV,FLV 等格式。

    2.Mac FoneLab Screen Recorder for mac 屏幕录像机

    Mac FoneLab Screen Recorder是一款屏幕录像机软件,功能强大,使用便捷,需要的朋友欢迎下载使用!

    3.Camtasia 2021for Mac顶级屏幕录像视频编辑软件

    Camtasia 2021for Mac是应用在Mac上的顶级屏幕录像视频编辑软件,使用Camtasia 2021Mac破解版可以轻松记录屏幕上的活动,Keynote幻灯片,摄像机视频,麦克风或系统音频 - 所有的清晰度都令人耳目一新。记录在现场观众面前或桌面上。编辑完美。把它变成一个完美的高清质量的视频,分享流行的视频网站,苹果设备,您的网站,博客或任何你喜欢的地方。

    4.Movavi Screen Recorder for mac屏幕录像编辑软件

    Movavi Screen Recorder可以在屏幕上进行游戏,视频通话,绘画录制。同时screen recorder 破解版还可以进行摄像头和麦克风的录制。Screen Recorder for Mac使用非常简单,快速上手操作。

    5.RecordAnyVID for mac屏幕录像软件

    想要更好的捕捉你的Mac电脑屏幕吗?试试RecordAnyVID for mac吧!RecordAnyVID mac版是一款运行在MacOS平台上的屏幕录像软件。RecordAnyVID同时适用于Windows和Mac计算机,可以轻松同时捕捉任何屏幕活动和音频,你还可以自定义捕捉区域的尺寸,方便实用。

    6.Movavi Screen Recorder for Mac屏幕录像编辑软件

    还在因为没有一款好用的屏幕录像编辑软件而烦恼吗?Movavi Screen Recorder 11 for Mac(屏幕录像编辑软件)是一款支持屏幕录像和屏幕截图的强大神器,可以快速进行屏幕录像并且编辑,还有多种特效滤镜可以选择哦。可以用于视频录像、音频录制或者游戏的录屏等操作。

    以上就是小编给大家带来的6款支持M1屏幕录像工具,有您需要的吗?更多实用MacAPP,尽在macz!

    展开全文
  • android屏幕录像

    2015-11-16 21:21:23
    import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.os.Environment; import ...

    实现原理:

    利用Java反射机制,获取WindowManagerImpl,该类里面有一个mViews的参数,它就是存放最终输出到界面的view视图,把这些视图保存在文件中为png,最后播放的时候从文件中拿出来即可。


    一个Activity,一个后台Service既可以完成:

    package com.jack.screenrecorder;
    
    import java.io.File;
    import java.util.Arrays;
    import java.util.Comparator;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.Bundle;
    import android.os.Environment;
    import android.os.Handler;
    import android.os.Message;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.ImageView;
    import android.widget.Toast;
    
    import com.jack.service.RecoderService;
    
    
    
    public class MainActivity extends Activity implements OnClickListener{
    	
    	private static final String TAG = "MainActivity";
    	private EditText input;
    	private File[] arrayOfFile2;
    	private ImageView playView;
    	private MainActivityHandler mHandler;
    	private boolean flagPlay = false;
    	private boolean flagRecorder = false;
    	private Button play,recorder,delete;
    	
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            input = (EditText)this.findViewById(R.id.input);
            playView = (ImageView)this.findViewById(R.id.playView);
            playView.setImageResource(R.drawable.ic_launcher);
            mHandler = new MainActivityHandler();
            
            play = (Button)this.findViewById(R.id.startPlay);
            recorder = (Button)this.findViewById(R.id.startRecorder);
            delete = (Button)this.findViewById(R.id.delete);
            play.setOnClickListener(this);
            recorder.setOnClickListener(this);
            delete.setOnClickListener(this);
            Log.i(TAG, Environment.getExternalStorageState());
        }
    
        
        
        @Override
    	protected void onStart() {
    		// TODO Auto-generated method stub
        	super.onStart();
        	int[] lo = new int[2];
        	input.getLocationOnScreen(lo);
        	Log.i(TAG, "input x y :" + lo[0] + lo[1]);
        	
        	playView.getLocationOnScreen(lo);
        	Log.i(TAG, "playView x y :" + lo[0] + lo[1]);
        	
        	playView.getLocationInWindow(lo);
        	Log.i(TAG, "playView x y :" + lo[0] + lo[1]);
    	}
    
    
    
    	/**
         * 开始录制方法
         */
        public void startRecorder(){
        	Log.i(TAG, "startRecorder");
        	flagRecorder = true;
        	recorder.setText("停止录制");
        	Intent intent = new Intent(this,RecoderService.class);
        	intent.putExtra("isStart", flagRecorder);
        	startService(intent);
        }
        
        public void endRecorder(){
        	Log.i(TAG, "endRecorder");
        	flagRecorder = false;
        	recorder.setText("开始录制");
        	Intent intent = new Intent(this,RecoderService.class);
        	stopService(intent);
        }
        
        /**
         * 开始播放方法
         */
        public void startPlay(){
        	flagPlay = true;
        	Log.i(TAG, "startPlay");
        	play.setText("停止播放");
        	arrayOfFile2 = getFileList();
        	
        	mHandler.setCount(0);
        	
        	mHandler.sendEmptyMessageDelayed(RecoderService.MSG_WHAT, RecoderService.MSG_DELEAY);
        }
        
        /**
         * 停止播放
         */
        public void endPlay(){
        	flagPlay = false;
        	Log.i(TAG, "endPlay");
        	play.setText("开始播放");
        	mHandler.removeMessages(RecoderService.MSG_WHAT);
        }
    
        /**
         * 获取存储卡里面路径下的文件列表
         * @return
         */
        public File[] getFileList(){
        	
        	File localFile1 = Environment.getExternalStorageDirectory();
        	File localFile2 = new File(localFile1, RecoderService.PATH);
        	
        	//该路径创建不成功
        	if(!localFile2.exists()){
        		return null;
        	}
        	//返回该路径下的文件列表
        	File[] fileList = localFile2.listFiles();
        	
        	//把文件拿来排序,存放文件时名字为日期,将日期转为long型数据进行排序
        	Arrays.sort(fileList, new Comparator<File>() {
    
    			@Override
    			public int compare(File arg0, File arg1) {
    				// TODO Auto-generated method stub
    				Long preFileLength1 = Long.valueOf(getPreFileName(arg0.getName()));
    				
    				long preFileLength2 = Long.valueOf(getPreFileName(arg1.getName()));
    				
    				
    				return (int)(preFileLength1-preFileLength2);
    			}
        		
    		});
        	
        	
        	return fileList;
        }
        
        /**
         * 获取filename的前缀名
         * @param filename
         * @return
         * 如:20150305.jpg    === >>>  20150305
         */
        public String getPreFileName(String filename){
        	String preFileName = null;
        	
        	if(filename == null || filename.length() < 1){
        		Log.i(TAG, "当前文件名为空或长度小于1");
        		return null;
        	}
        	
        	int i = filename.lastIndexOf('.');
        	if(i != -1){
        		int j = filename.length();
        		if(i < j){
        			preFileName = filename.substring(0, i);
        		}
        	}
        	
        	return preFileName;
        }
        
        private class MainActivityHandler extends Handler{
    
        	private int count = 0;
        	
        	public void setCount(int value){
        		count = value;
        	}
        	
        	public int getCount(){
        		return count;
        	}
        	
    		@Override
    		public void handleMessage(Message msg) {
    			// TODO Auto-generated method stub
    			if(arrayOfFile2 != null && count < arrayOfFile2.length){
    				Bitmap localBitmap = BitmapFactory.decodeFile(arrayOfFile2[count++].getAbsolutePath());		//获取该路径下的文件   并转换为bitmap
    				playView.setImageBitmap(localBitmap);
    				localBitmap.recycle();
    				
    				//延迟发送message
    				if(flagPlay){
    					mHandler.sendEmptyMessageDelayed(RecoderService.MSG_WHAT, RecoderService.MSG_DELEAY);
    				}
    				
    			}
    		}
        	
        }
    
    	@Override
    	public void onClick(View arg0) {
    		// TODO Auto-generated method stub
    		switch(arg0.getId()){
    		case R.id.startPlay:
    			if(flagPlay){
    				endPlay();
    			}else{
    				if(!flagRecorder){
    					startPlay();
    				}else{
    					Toast.makeText(MainActivity.this, "请先关闭录制功能", Toast.LENGTH_SHORT).show();
    				}
    				
    			}
    			break;
    			
    		case R.id.startRecorder:
    			if(flagRecorder){
    				endRecorder();
    			}else{
    				if(!flagPlay){
    					startRecorder();
    				}else{
    					Toast.makeText(MainActivity.this, "请先关闭播放功能", Toast.LENGTH_SHORT).show();
    				}
    			}
    			break;
    		case R.id.delete:
    			if(!flagRecorder && !flagPlay){
    				Log.i(TAG, "delete file");
    				deleteRecorderFile();
    			}else{
    				Toast.makeText(MainActivity.this, "请关闭录制和播放功能", Toast.LENGTH_SHORT);
    			}
    			break;
    			
    		default:
    			break;
    		}
    	}
    
    	public void deleteRecorderFile(){
    		File[] file1 = this.getFileList();
    		
    		for(File file : file1){
    			if(file.isFile() || file.exists()){
    				file.delete();
    			}
    		}
    	}
    
    	@Override
    	protected void onDestroy() {
    		// TODO Auto-generated method stub
    		super.onDestroy();
    		int[] lo = new int[2];
        	input.getLocationOnScreen(lo);
        	Log.i(TAG, "input x y :" + lo[0] + lo[1]);
        	
        	playView.getLocationOnScreen(lo);
        	Log.i(TAG, "playView x y :" + lo[0] + lo[1]);
        	
        	playView.getLocationInWindow(lo);
        	Log.i(TAG, "playView x y :" + lo[0] + lo[1]);
    	}
    
    
    
    	@Override
    	protected void onPause() {
    		// TODO Auto-generated method stub
    		super.onResume();
    		int[] lo = new int[2];
        	input.getLocationOnScreen(lo);
        	Log.i(TAG, "onPause input x y :" + lo[0] + lo[1]);
        	
        	playView.getLocationOnScreen(lo);
        	Log.i(TAG, "playView x y :" + lo[0] + lo[1]);
        	
        	playView.getLocationInWindow(lo);
        	Log.i(TAG, "playView x y :" + lo[0] + lo[1]);
    	}
        
    	
    	
    }
    


    后台Service:

    package com.jack.service;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.lang.reflect.Field;
    
    import android.app.Service;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.graphics.Bitmap.Config;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.os.Environment;
    import android.os.Handler;
    import android.os.IBinder;
    import android.os.Message;
    import android.util.Log;
    import android.view.View;
    
    
    public class RecoderService extends Service{
    
    	private static final String TAG = "RecoderService";
    	public static final int MSG_WHAT = 256;
    	public static final long MSG_DELEAY = 100L;
    	public static final String PATH = "/recoder/";
    	private boolean isStart = false;
    	
    	
    	@Override
    	public IBinder onBind(Intent arg0) {
    		// TODO Auto-generated method stub
    		return null;
    	}
    
    	@Override
    	public void onCreate() {
    		// TODO Auto-generated method stub
    		super.onCreate();
    		Log.i(TAG, "onCreate()...");
    	}
    
    	@Override
    	public void onDestroy() {
    		// TODO Auto-generated method stub
    		super.onDestroy();
    		Log.i(TAG, "end Service()===========================================");
    		Log.i(TAG, "end Service()===========================================");
    		Log.i(TAG, "end Service()===========================================");
    		isStart = false;
    	}
    
    	@Override
    	public int onStartCommand(Intent intent, int flags, int startId) {
    		// TODO Auto-generated method stub
    		Log.i(TAG, "onStartCommand()===========================================");
    		Log.i(TAG, "onStartCommand()===========================================");
    		Log.i(TAG, "onStartCommand()===========================================");
    		boolean flag = intent.getBooleanExtra("isStart", false);
    		
    		//如果传递过来的值时开启就开启  否则不开启
    		if(flag != isStart){
    			isStart = flag;
    			if(isStart){
    				mHandler.sendEmptyMessageDelayed(MSG_WHAT, MSG_DELEAY);
    			}else{
    				mHandler.removeMessages(MSG_WHAT);
    			}
    		}
    		
    		return super.onStartCommand(intent, flags, startId);
    	}
    
    	@Override
    	public boolean onUnbind(Intent intent) {
    		// TODO Auto-generated method stub
    		return super.onUnbind(intent);
    	}
    	
    	/**
    	 * 排序views,以view的绝对坐标
    	 * @param viewArray
    	 * @return
    	 */
    	public View[] sortViews(View[] viewArray){
    		if(viewArray == null || viewArray.length <= 0){
    			Log.i(TAG, "sortView() paramter viewArray is null");
    			return null;
    		}
    		
    		int i = 0;
    		View[] views = new View[viewArray.length];
    		for(View view : viewArray){
    			views[i++] = view;
    		}
    		
    		//sort the view
    		int length = views.length;
    		int[] arrayInt = new int[2];
    		for(i = 0; i < length; i++){
    			View localView = views[i];
    			localView.getLocationOnScreen(arrayInt);
    			if(arrayInt[0] > 0 && arrayInt[1] > 0){
    				for(int j = i+1; j < views.length; i++){
    					views[j-1] = views[j];
    				}
    				views[views.length-1] = localView;
    				i--;
    				length--;
    			}
    		}
    		
    		return views;
    	}
    
    	/**
    	 * 
    	 * @return views[]s
    	 */
    	public View[] getWindowDecorViewDownApi15(){
    		View[] view = null;
    		try {
    			Log.i(TAG, "getWindowDecorViewDownApi15");
    			Class<?> windowManager = Class.forName("android.view.WindowManagerImpl");
    			Field viewFiled = windowManager.getDeclaredField("mViews");
    			Field instanceFiled = windowManager.getDeclaredField("mWindowManager");
    			viewFiled.setAccessible(true);
    			instanceFiled.setAccessible(true);		//可修改
    			
    			Object instance = instanceFiled.get(null);
    			view = (View[]) viewFiled.get(instance);
    		} catch (ClassNotFoundException e) {
    			// TODO Auto-generated catch block
    			Log.i(TAG, "getWindowDecorViewDownApi15() ClassNotFoundException " + e.toString());
    			e.printStackTrace();
    		} catch (NoSuchFieldException e) {
    			// TODO Auto-generated catch block
    			Log.i(TAG, "getWindowDecorViewDownApi15() NoSuchFieldException " + e.toString());
    			e.printStackTrace();
    		} catch (IllegalAccessException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (IllegalArgumentException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		
    		return sortViews(view);
    	}
    	
    	/**
    	 * 
    	 * @return
    	 */
    	public View[] getWindowDecorViewsApi14_16(){
    		View[] view = null;
    		try {
    			Log.i(TAG, "getWindowDecorViewsApi14_16");
    			Class<?> windowManager = Class  
    	                .forName("android.view.WindowManagerImpl");       
    	        Field viewsField = windowManager.getDeclaredField("mViews");  
    	        Field instanceField = windowManager.getDeclaredField("sWindowManager"); 
    	        viewsField.setAccessible(true);
    	        instanceField.setAccessible(true);		//可修改
    			
    			Object instance = instanceField.get(null);
    			view = (View[]) viewsField.get(instance);
    		} catch (ClassNotFoundException e) {
    			// TODO Auto-generated catch block
    			Log.i(TAG, "getWindowDecorViewDownApi15() ClassNotFoundException " + e.toString());
    			e.printStackTrace();
    		} catch (NoSuchFieldException e) {
    			// TODO Auto-generated catch block
    			Log.i(TAG, "getWindowDecorViewDownApi15() NoSuchFieldException " + e.toString());
    			e.printStackTrace();
    		} catch (IllegalAccessException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (IllegalArgumentException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		
    		return sortViews(view);
    	}
    	
    	public View[] getWindowDecorViewsApiUp17(){
    		View[] view = null;
    		try {
    			Log.i(TAG, "getWindowDecorViewsApiUp17");
    			Class<?> windowManager = Class  
    	                .forName("android.view.WindowManagerGlobal");         
    	        Field viewsField = windowManager.getDeclaredField("mViews");  
    	        Field instanceField = windowManager.getDeclaredField("sDefaultWindowManager");  
    	        viewsField.setAccessible(true);
    	        instanceField.setAccessible(true);		//可修改
    			
    			Object instance = instanceField.get(null);
    			view = (View[]) viewsField.get(instance);
    		} catch (ClassNotFoundException e) {
    			// TODO Auto-generated catch block
    			Log.i(TAG, "getWindowDecorViewDownApi15() ClassNotFoundException " + e.toString());
    			e.printStackTrace();
    		} catch (NoSuchFieldException e) {
    			// TODO Auto-generated catch block
    			Log.i(TAG, "getWindowDecorViewDownApi15() NoSuchFieldException " + e.toString());
    			e.printStackTrace();
    		} catch (IllegalAccessException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (IllegalArgumentException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		
    		return sortViews(view);
    	}
    	
    	/**
    	 * 根据不同的sdk版本采取不同的方法获取图片
    	 * @return
    	 */
    	private View[] getWindowDecorViews(){
    		View[] views = null;
    		
    		if(android.os.Build.VERSION.SDK_INT >= 14 && android.os.Build.VERSION.SDK_INT < 17){
    			views = getWindowDecorViewsApi14_16();
    		}else if(android.os.Build.VERSION.SDK_INT >= 17){
    			views = getWindowDecorViewsApiUp17();
    		}else{
    			views = getWindowDecorViewDownApi15();
    		}
    		
    		return views;
    	}
    	
    	/**
    	 * 从底层获取view在转换为bitmap,在保存到文件
    	 */
    	public void screenShot(){
    		try {
    			View[] views = getWindowDecorViews();
    			
    			Bitmap bitmap = viewsToBitmap(views);
    			
    			new Thread(new SavePicThread(bitmap)).start();
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			Log.i(TAG, "screenshot() has a error. " + e.toString()); 
    		}
    	}
    	
    	/**
    	 * 
    	 * @param view
    	 * @return Bitmap
    	 */
    	public Bitmap viewToBitmap(View view){
    		Log.i(TAG, "turn view to bitmap");
    		/**
    		 * set缓冲方便下次调用getDrawingCache把view画到一个bitmap里面去
    		 */
    		view.setDrawingCacheEnabled(true);
    		view.buildDrawingCache();
    		Bitmap bitmap1 = view.getDrawingCache();
    		Bitmap bitmap2 = null;
    		if(bitmap1 != null){
    			bitmap2 = Bitmap.createBitmap(bitmap1);
    		}
    		view.destroyDrawingCache();
    		
    		return bitmap2;
    	}
    	
    	/**
    	 * 将几个view画到一个bitmap有点不懂为什么
    	 * @param arrayView
    	 * @return
    	 */
    	public Bitmap viewsToBitmap(View[] arrayView){
    		Log.i(TAG, "turn viewssss to bitmap");
    		Canvas localCanvas = null;
    		Paint mPaint = null;
    		Bitmap newBitmap = null;
    		int[] location = new int[2];
    		
    		Bitmap localBitmap = null;
    		for(View view : arrayView){
    			localBitmap = viewToBitmap(view);
    			view.getLocationOnScreen(location);
    			//画一个和view尺寸大小的画布
    			if(null == localCanvas){
    				newBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Config.ARGB_8888);
    				localCanvas = new Canvas(newBitmap);
    				mPaint = new Paint();
    				mPaint.setAntiAlias(true);
    			}
    			
    			localCanvas.drawBitmap(localBitmap, location[0], location[1], mPaint);
    			localBitmap.recycle();
    			localBitmap = null;
    		}
    		
    		if(localCanvas != null){
    			localCanvas.save(Canvas.ALL_SAVE_FLAG);
    			localCanvas.restore();
    		}
    		
    		return newBitmap;
    	}
    	
    	/**
    	 * b保存bitmap为图片
    	 * @param paramBitmap
    	 * @param paramString
    	 */
    	public void savePic(Bitmap paramBitmap, String paramString){
    		FileOutputStream fsStream = null;
    		
    		try {
    			fsStream = new FileOutputStream(paramString);
    			if(fsStream != null){
    				paramBitmap.compress(Bitmap.CompressFormat.PNG, 90, fsStream);			//压缩保存
    				
    				fsStream.flush();
    				fsStream.close();
    			}
    			
    		} catch (FileNotFoundException e) {
    			// TODO Auto-generated catch block
    			
    			Log.i(TAG, e.toString());
    			Log.i(TAG, "savePic() paramString is not exist" + paramString);
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			Log.i(TAG, "savePic() close() flush() is error!");
    		}
    	}
    	
    	/**
    	 * 保存图片线程
    	 * @author JackZhouYu
    	 * 将内存中的bitmap写到file里面去,因为是一个比较耗时的工作,所以开线程存储
    	 */
    	private class SavePicThread implements Runnable{
    
    		private Bitmap bitmap;
    		
    		public SavePicThread(Bitmap bitmap){
    			this.bitmap = bitmap;
    		}
    		
    		@Override
    		public void run() {
    			// TODO Auto-generated method stub
    			File file1 = Environment.getExternalStorageDirectory();
    			File file2 = new File(file1,PATH);
    			//创建目录
    			if(!file2.exists()){
    				file2.mkdir();
    			}
    			
    			String filename = file2.getAbsolutePath() + "/" + System.currentTimeMillis() + ".png";
    			Log.i(TAG, "save pic to file " + filename);
    			
    			savePic(bitmap, filename);
    			
    			bitmap.recycle();
    			bitmap = null;
    		}
    		
    	}
    	
    	
    
    	private Handler mHandler = new Handler(){
    
    		@Override
    		public void handleMessage(Message msg) {
    			
    			Log.i(TAG, "mHandler i got message");
    			// TODO Auto-generated method stub
    			if(msg.what == MSG_WHAT){
    				RecoderService.this.screenShot();
    				if(isStart){
    					mHandler.sendEmptyMessageDelayed(MSG_WHAT, MSG_DELEAY);
    				}
    			}
    		}
    		
    	};
    	
    }
    


    但是,这只能录制当前App下的图像

    展开全文
  • Androidscreencastcase 一个适用于Windows/Linux/MacOS 平台控制任何android 设备,通过USB连接就可实现鼠标键盘控制你... Desktop app to control an android device remotely using mouse and keyboard. Should work
  • 笔者下载了一些学习资料,但是格式是exe,只能在windows下才能播放,使用屏幕录像专家的转换功能一次只能转换1部视频,还得手动点击,非常麻烦,经过查询发现了一个python脚本可以批量转换。# -*- coding: utf-8 -*-...
  • Android开发的APP录像功能,屏幕熄灭或者APP退到后台录像就自动停了。有没有大佬给指点一下怎么解决?感激涕零!!!
  • android 屏幕录像实现过程

    千次阅读 2015-08-02 18:54:46
    接到上面的需求,要实现一个安卓手机屏幕录像的功能。 正常且直接的思路是想到使用某种手段得到足够多的屏幕图片frame.而后使用开源ffmpeg来进行图片到指定视频的转换 。 本人觉得在手机上实现此功能的缺点...
  • Qt桌面屏幕录像软件

    2017-06-13 10:20:27
    支持跨平台使用,linux等 源代码
  • 公司要实现对被攻击ip的统计,我这边简单实现了自动化,通过按键精灵实现从阿里云中心爬多页数据,c++写了一个简单的过滤程序,屏幕录像专家进行整个过程录制
  • 屏幕录像软件可以把显示器上的每一帧画面都抓取下来,并保存成一段连续的动画,无论你是想做一个演示教程,还是想把和你视频聊天的美女录下来,都是一个不错的选择。还在寻找屏幕录像专家破解版?这五个最好的屏幕...
  • 屏幕录像专家录制超清视频教程 十几年管理软件开发实战经验。从事IT行业十 余...
  • ·1、使用:屏幕录像专家20170328,最新版本不能转换其他人录制的exe视频 2、python脚本,修改自python自动化工具之pywinauto(四)——批量转换exe视频_shawpan的专栏-CSDN博客 原脚本我不能正常运行,添加了time....
  • 屏幕框 ScreenKap是适用于Android的简单屏幕记录器应用程序。 它使用或 API来访问文件,因此不需要存储许可。 屏幕截图 | | | | 执照 Copyright (c) 2020 Indrit Bashkimi Licensed under the Apache License, ...
  • 屏幕录像机(bb flashback pro 4)pjb v4.1.21

    千次阅读 2020-10-07 17:20:20
    flashback pro 4是来自英国的Blueberry Software开发的一款功能强大的屏幕录像机,使用它可以帮助用户完整录制自己的屏幕、声音和网络摄像头,同时该软件还拥有强大的编辑工具,方便大家对录制的结果进行编辑等操作...
  • 一小时快速学习屏幕录像和视频编辑实战教程 擅长于photoshop、Adob...
  • 这意味着该库应与“ app”模块处于同一级别。 然后将这些行添加到相应的文件夹中: settings.gradle include ':library' build.gradle compile project(':library') ### 2)初始化 现在,您可以在项目中使用...
  • 除了各项亮眼功能外,Win10此次还新增加了一项非常有趣的小功能,即允许用户自己录制屏幕视频。不过由于这项功能相对比较隐蔽,很多小伙伴到现在还不知道。今天小编就和大家聊一聊,如何利用这项功能录制屏幕视频。 ...
  • Android屏幕录像转换GIF解决方案

    千次阅读 2016-05-17 13:49:02
    再去问谷歌,谷歌第一条就给了我一系列专门用于屏幕录制的app,各有特色,原文地址:http://www.hongkiat.com/blog/android-screen-recording-apps/ 这里推荐一款我用起来感觉还不错的一款app:Rec.  Google...
  • http://apps.hi.baidu.com/share/detail/18088320
  • 于是乎,结合同学们的问题,我用wx写了一个屏幕录像机代码,既包含任务托盘的实现,也用到了异形窗口,还使用了DC绘制录像窗口边框。这段代码,可以很方便地打包成exe程序。程序启动后,栖身于任务托盘。你需要的...
  • FFmpeg音视频编码实战屏幕录像机视频课程-基于QT5和FFMpegSDK ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,341
精华内容 1,736
关键字:

屏幕录像app