Android中抓取手机视频流数据。

2023-05-16

目前实时抓取手机视频数据有2种方法,一种是通过camera的回调获取源数据,这里获取的源数据是没有编码的数据。

有的人发送yuv数据然后在那绘制图片,也说视频聊天,真是可笑。这种方式是可是实现视频聊天的,但是需要移植编码库

目前可移植的有,android的opencore编码,参考http://www.shouyanwang.org/thread-184-1-1.html。

ffmpeg编码,这个网上很难找,但是也有人实现哦。(编码效率好,但是支持不了高清视频)

编码完成可以通过rtp协议发送。就可以视频啦。rtp协议什么的就不说了哦。

以上方法的代码,在这个链接最好回复我贴了代码,不是完整的。链接:http://www.eoeandroid.com/thread-51460-1-1.html

第2种方法,也就是我用的方法。

通过MediaRecorder录制。然后绑定一个localsocket,可以获取编码后的视频数据传输;

代码如下:

package com.pei;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import android.app.Activity;
import android.os.Bundle;
import android.graphics.PixelFormat;
import android.media.MediaRecorder;
import android.net.LocalServerSocket;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

/**
 * class name:VideoCameraActivity<BR>
 * class description:CATCH THE VIDEODATA SEND TO RED5<BR>
 * PS: <BR>
 * 
 * @version 1.00 2011/11/05
 * @author CODYY)peijiangping
 */
public class VideoCameraActivity extends Activity implements
		SurfaceHolder.Callback, MediaRecorder.OnErrorListener,
		MediaRecorder.OnInfoListener {
	private static final int mVideoEncoder = MediaRecorder.VideoEncoder.H264;
	private LocalSocket receiver, sender;
	private LocalServerSocket lss;
	private MediaRecorder mMediaRecorder = null;
	private boolean mMediaRecorderRecording = false;
	private SurfaceView mSurfaceView = null;
	private SurfaceHolder mSurfaceHolder = null;
	private Thread t;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		getWindow().setFormat(PixelFormat.TRANSLUCENT);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setContentView(R.layout.main);
		mSurfaceView = (SurfaceView) this.findViewById(R.id.surface_camera);
		SurfaceHolder holder = mSurfaceView.getHolder();
		holder.addCallback(this);
		holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		mSurfaceView.setVisibility(View.VISIBLE);
		receiver = new LocalSocket();
		try {
			lss = new LocalServerSocket("VideoCamera");
			receiver.connect(new LocalSocketAddress("VideoCamera"));
			receiver.setReceiveBufferSize(500000);
			receiver.setSendBufferSize(500000);
			sender = lss.accept();
			sender.setReceiveBufferSize(500000);
			sender.setSendBufferSize(500000);
		} catch (IOException e) {
			finish();
			return;
		}
	}

	@Override
	public void onPause() {
		super.onPause();
		if (mMediaRecorderRecording) {
			stopVideoRecording();
			try {
				lss.close();
				receiver.close();
				sender.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		finish();
	}

	private void stopVideoRecording() {
		System.out.println("stopVideoRecording");
		if (mMediaRecorderRecording || mMediaRecorder != null) {
			if (t != null)
				t.interrupt();
			releaseMediaRecorder();
		}
	}

	private void startVideoRecording() {
		(t = new Thread() {
			public void run() {
				int frame_size = 20000;
				byte[] buffer = new byte[1024 * 64];
				int num, number = 0;
				InputStream fis = null;
				try {
					fis = receiver.getInputStream();
				} catch (IOException e1) {
					return;
				}
				number = 0;
				releaseMediaRecorder();
				while (true) {
					System.out.println("ok");
					try {
						num = fis.read(buffer, number, frame_size);
						number += num;
						if (num < frame_size) {
							System.out.println("recoend break");
							break;
						}
					} catch (IOException e) {
						System.out.println("exception break");
						break;
					}
				}
				initializeVideo();
				number = 0;
				Consumer consumer = new Publisher();// Publisher继承了Consumer
				Thread consumerThread = new Thread((Runnable) consumer);
				consumer.setRecording(true);// 设置线程状态;
				consumerThread.start();// 开始发布数据流
				DataInputStream dis = new DataInputStream(fis);
				try {
					dis.read(buffer, 0, 32);
				} catch (IOException e1) {
					e1.printStackTrace();
				}
				byte[] aa = { 0x01, 0x42, (byte) 0x80, 0x0A, (byte) 0xFF,
						(byte) 0xE1, 0x00, 0x12, 0x67, 0x42, (byte) 0x80, 0x0A,
						(byte) 0xE9, 0x02, (byte) 0xC1, 0x29, 0x08, 0x00, 0x00,
						0x1F, 0x40, 0x00, 0x04, (byte) 0xE2, 0x00, 0x20, 0x01,
						0x00, 0x04, 0x68, (byte) 0xCE, 0x3C, (byte) 0x80 };
				consumer.putData(System.currentTimeMillis(), aa, 33);
				while (true) {
					try {
						int h264length = dis.readInt();
						number = 0;
						while (number < h264length) {
							int lost = h264length - number;
							num = fis.read(buffer, 0,
									frame_size < lost ? frame_size : lost);
							number += num;
							consumer.putData(System.currentTimeMillis(),
									buffer, num);
						}
					} catch (IOException e) {
						break;
					}
				}
				consumer.setRecording(false);// 设置线程状态;
			}
		}).start();
	}

	private boolean initializeVideo() {
		System.out.println("initializeVideo");
		if (mSurfaceHolder == null)
			return false;
		mMediaRecorderRecording = true;
		if (mMediaRecorder == null)
			mMediaRecorder = new MediaRecorder();
		else
			mMediaRecorder.reset();
		mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
		mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
		mMediaRecorder.setVideoFrameRate(20);
		mMediaRecorder.setVideoSize(352, 288);
		mMediaRecorder.setVideoEncoder(mVideoEncoder);
		mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
		mMediaRecorder.setMaxDuration(0);
		mMediaRecorder.setMaxFileSize(0);
		mMediaRecorder.setOutputFile(sender.getFileDescriptor());
		try {
			mMediaRecorder.setOnInfoListener(this);
			mMediaRecorder.setOnErrorListener(this);
			mMediaRecorder.prepare();
			mMediaRecorder.start();
		} catch (IOException exception) {
			releaseMediaRecorder();
			finish();
			return false;
		}
		return true;
	}

	private void releaseMediaRecorder() {
		System.out.println("Releasing media recorder.");
		if (mMediaRecorder != null) {
			if (mMediaRecorderRecording) {
				try {
					mMediaRecorder.setOnErrorListener(null);
					mMediaRecorder.setOnInfoListener(null);
					mMediaRecorder.stop();
				} catch (RuntimeException e) {
					System.out.println("stop fail: " + e.getMessage());
				}
				mMediaRecorderRecording = false;
			}
			mMediaRecorder.reset();
			mMediaRecorder.release();
			mMediaRecorder = null;
		}
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
		System.out.println("surfaceChanged");
		mSurfaceHolder = holder;
		if (!mMediaRecorderRecording) {
			initializeVideo();
			startVideoRecording();
		}
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		System.out.println("surfaceCreated");
		mSurfaceHolder = holder;
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		System.out.println("surfaceDestroyed");
		mSurfaceView = null;
		mSurfaceHolder = null;
		mMediaRecorder = null;
		if (t != null) {
			t.interrupt();
		}
	}

	@Override
	public void onInfo(MediaRecorder mr, int what, int extra) {
		switch (what) {
		case MediaRecorder.MEDIA_RECORDER_INFO_UNKNOWN:
			System.out.println("MEDIA_RECORDER_INFO_UNKNOWN");
			break;
		case MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED:
			System.out.println("MEDIA_RECORDER_INFO_MAX_DURATION_REACHED");
			break;
		case MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED:
			System.out.println("MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED");
			break;
		}
	}

	@Override
	public void onError(MediaRecorder mr, int what, int extra) {
		if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {
			System.out.println("MEDIA_RECORDER_ERROR_UNKNOWN");
			finish();
		}
	}

}



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android中抓取手机视频流数据。 的相关文章

  • 有没有一种方法可以在不使用意图的情况下在活动之间发送数据?

    我有一个对于每个用户来说都是唯一的用户名 我想将其发送到某个活动 但我不想使用意图 create an intent and sends username Intent intent new Intent RegisterOwner thi
  • 如何在android中批量插入sqlite

    我正在使用 SQLiteOpenHelper 进行数据插入 我需要插入2500个id和2500个名字 所以花费了太多时间 请任何人帮助我如何减少插入时间 我们可以一次插入多条记录吗 任何人都可以帮助我 先感谢您 代码 public clas
  • app-release-unsigned.apk 未签名

    我在 github 上下载了 Android 应用程序的 zip 文件 并尝试运行它 但出现一个包含此消息的对话框 app release unsigned apk is not signed Please configure the si
  • Android 片段之间的阴影分隔符

    我有一个类似于平板电脑的 ICS Gmail 应用程序的布局 ListFragment左边是内容 右边是内容 我想知道如何构建布局 使两个片段之间有一个阴影分隔符 就像在 Gmail 应用程序中一样 如下所示 另外 由于这适用于这个问题 我
  • 使用Picasso从url保存图像?

    我正在尝试使用 API Picasso 保存图像 为了做到这一点 我正在尝试使用Target保存 但我无法完成这项工作 我怎么能这样做呢 Trying save image public static void imageDownload
  • 如何在Android中访问现有的sqlite数据库?

    到目前为止 我们已经在 Android 中开发了在运行时创建数据库的应用程序 我们想知道如何在 Android 应用程序中访问预构建或现有的数据库 sqlite 文件 请提供详细信息 查看文档android database sqlite
  • 尝试获取屏幕上绘制的每个随机圆圈的 x、y 坐标

    您好 我正在制作一款游戏 该游戏将在屏幕上创建随机圆圈 随机创建的圆圈的值为红色或绿色 我的问题是 我希望不仅能够确定用户何时单击其中一个圆圈 而且还能够确定他们最终单击的圆圈 红色或绿色 下面是我的代码 我的主要问题是试图找到将要绘制的圆
  • 有人可以给出一个 android 中 webview 实现的确切例子吗

    嗨 我正在使用开发 Android 应用程序WebView执行 我跟着官方安卓教程 http developer android com resources tutorials views hello webview html 在 Ecli
  • startActivityForResult中的requestCode是什么意思

    我想知道我是否正确理解 requestCode 的概念 这个整数的用途是什么 我将其设置为哪个整数有关系吗 private static int CAMERA REQUEST 谢谢 requestCode 可帮助您识别您从哪个 Intent
  • Android ViewModel LiveData 在按钮单击时更新视图

    我正在关注这个tutorial https developer android com topic libraries architecture guide html common problems faced by app develop
  • 该项目可能使用的 Gradle 版本不包含“compileSdkVersion()”方法

    当我尝试运行最初在 Eclipse ADT 上创建的项目时 我遇到了这个问题 Error 17 0 Gradle DSL method not found compileSdkVersion Possible causes ul li Th
  • java.net.ProtocolException:流意外结束

    我面临一个奇怪的问题 并且无法调试它 我已经实现了上传数据流的逻辑 并使用 Volley 来实现相同的功能 我在HurlStack addBodyIfExistsapi 以便可以处理 application octet stream 类型的
  • 垂直从上到下线手势检测器

    我用的是 手势工具 注意到对于垂直从上到下的线无法检测 因为我在代码中使用生成的手势文件 如下所示 但无法检测垂直从上到下的线手势检测 import java util ArrayList import android app Activi
  • Android OptionsMenu问题,背景始终透明

    我的选项菜单总是不显示背景 背景是透明的 有谁知道如何摆脱这个 我的失败起源活动是从另一个自定义活动扩展的 我在 eclipse 上有这个项目 选项菜单工作正常 但自从我迁移到 AndroidStudio 后 选项菜单始终是透明的 我尝试更
  • 可用屏幕的尺寸

    我使用的是 Nexus 7 1280x800 android 4 2 2 API 17 我想获取屏幕的大小 将其划分为相同高度和宽度的正方形部分 我正在使用 FrameLayout 我的方块是 ImageView 的子类 我这样做 cont
  • 在循环中按名称访问变量

    我正在开发一个 Android 项目 并且有很多可绘制对象 这些绘图的名称都类似于icon 0 png icon 1 png icon 100 png 我想将这些可绘制对象的所有资源 ID 添加到整数 ArrayList 中 对于那些不了解
  • Android项目中使用java获取电脑的IP地址

    我在用ksoap2 android http code google com p ksoap2 android 我需要使用java获取IP地址 这样我就不必每次都手动输入它 我所说的 IP 地址是指 例如 如果我这样做ipconfig使用命
  • Android Volley - 发布请求 - 无法在线工作

    我试图通过 Volley 发出 POST 请求 它在我的本地主机中工作得很好 但是当我将它移动到网络服务器时 响应为空 Java代码 RequestQueue queue Volley newRequestQueue this String
  • 在 Qt 中构建 Android 项目不再有效

    所以我对 Android SDK NDK 和 Apache Ant 进行了一些更新 现在我无法构建任何 Android 项目 我收到一条警告 然后它说找不到 build xml 文件 错误 Warning Android platform
  • Android 版本低于 Lollipop 时出现 java.lang.NoClassDefFoundError

    我有一台运行 Android 21 的 Nexus 5 设备 我正在测试我的项目 没有任何问题 但是 如果我使用 Google API 19 在模拟器上进行测试 则会显示错误java lang NoClassDefFoundError 如果

随机推荐

  • python-pcl安装及使用

    在开始前 xff0c 先说明一下 xff0c pcl的库安装不简单 xff0c 不仅需要pip安装 xff0c 还需要安装C 43 43 的pcl库 xff0c 所以整个流程会比较漫长 鉴于官方参考网站的python pcl太麻烦 xff0
  • ROSBAG解析bag包教程

    一 软件安装教程 1 安装rosbag xff1a https www cnblogs com arkenstone p 6676203 html 2 安装mjepgtools和ffmpeg sudo apt get install mje
  • 双电机同步PID调试方法(二)

    由于双电机的PID上升曲线难以完全重合 xff0c 造成左右电机速度不一致 本文为了解决该问题设计了一种方法 主要思想是将不同速度对应的PWM占空比曲线拟合出来 xff0c 减1000 xff08 总10000 xff09 占空比后作为预设
  • exe打包成安装包

    前面介绍了如何将python代码打包成可执行文件 xff0c 这里再介绍一下如何将exe打包成安装包 一 安装InstallShield2015 百度云网址 xff1a https pan baidu com s 1fFGDeczPduWa
  • Python 打包成 wheel

    1 编写 setup py 在项目的根目录下外面一个文件夹创建 96 setup py 96 96 name 96 xff1a 指的是你打包后发布的名称 xff08 如 96 numpy 96 和 96 torch 96 xff09 96
  • plugins插件使用例程

    最近在看一个pyqt写的工具软件 xff0c 项目中大量使用plugins xff0c 所以了解了一下plugins的功能机制 下面简单分享一个例程 xff0c 代码结构如下 main py platform py init py plug
  • pycharm中.gitignore无效

    1 打开pycharm的命令行 xff0c 输入以下指令 git rm r cached git add 2 再次在pycharm上 xff0c 点击commit 原因 xff1a 这是因为pycharm会自动运行git add 的功能 x
  • Jetson Orin&Nx&Nano平台 FPDlink Ⅲ相机采集---双目场景应用

    1 前言 基于上次在淘宝上采购的FPDlink 相机采集套件使用一段时间之后 不少人对此方案很感兴趣的 又激发了我继续写的激情 上次帖子链接如下 Jetson Orin平台多路 FPDlink 相机采集套装推荐 bingdund的博客 CS
  • SBUS协议:SBUS解析与合成

    在说协议之前 xff0c 我想强调一点 xff1a 信号要取反 xff0c 硬件取反 xff01 xff01 xff01 xff01 xff01 至于为什么强调 xff0c 我会在后面解释 xff0c 你们先记住 SBUS协议 xff1a
  • 上海灵信视觉A4控制板

    资料准备 xff1a 1 LED Player上位机控制 xff1a em span style font size 12px http www 168led com AjaxFile DownLoadFileNew aspx FilePa
  • stm32串口一直进USART1_IRQHandler

    今天在使用USART模块 xff0c 遇到了一些问题并解决了 xff0c 于是发贴共享 问题描述 xff1a 在使用USART做串口通讯时 xff0c 我只把接收中断打开 xff0c 并设置抢占优先级为最低一个级别 xff0c 而接收中断上
  • tensorflow载入报错Process finished with exit code -1073741819 (0xC0000005)

    这几天准备在现有的软件里加上caffe来测试一种新算法 发现windows下python3 6安装caffe是真的难 xff0c 只能装好python2 7的版本就放弃了 回来继续完善软件 xff0c 又发现软件里的tensorflow不能
  • python项目打包(自定义dll) anaconda3+pyinstaller

    目前手上有一个python 43 pyqt的项目需要打包 xff0c 所以查了一下打包的方法 下面介绍一下具体步骤 xff1a python打包有很多方法 xff0c py2exe xff0c pyinstaller等等 xff08 其实我
  • Docker(六)同一镜像有多个Tag情况下,执行 docker rmi 镜像ID 指令无法删除

    删除方法一 docker rmi f 镜像ID 删除方法二 docker rmi repository tag 参考 xff1a 1 https www imooc com article 35040
  • 《ROS机器人开发实践(胡春旭)》第十章MoveIt!机械臂控制 学习笔记

    r 在学习 ROS机器人开发实践 胡春旭 第10章的MoveIt xff01 时 xff0c 因为在自己创建的工作空间中没有下载作者的源代码 xff0c 所有有以下几个问题 xff1a 1 使用moveit setup assistant时
  • Android 根据网络分析运营商信息

    我们想获取手机的运营商信息 通常都会去调用系统的TelephonyManager类的取数据 但是很多时候可能取不到卡的信息 xff08 例如双卡手机和一些特殊卡 xff09 xff0c 这样就区别不了运营商了 但是有时候我们的需求要进行不通
  • 简单又好看的按钮,扁平化按钮。

    今天分享一下流行的扁平化按钮 完全不需要用到图片哦 效果图如下 xff1a 里面有2个按钮都是一样的模式 只要修改的色值就可以 下面跟我来更新你的UI吧 首先编写 button xml 代码如下 lt xml version 61 34 1
  • Android 获取运营商信息(完整版)-解决高通,MTK等双卡问题

    由于国内的运营商问题 xff0c 双卡手机获取IMSI号问题要根据厂商API 来实现 下面我们就来做一套完整的分析运营商获取IMSI号逻辑 1 xff0c 首先我们要判断手机的平台 1 1 xff0c 判断手机是否MTK平台 public
  • AstarPathfindingProject 中RVO碰撞体扩展

    原本库中只有矩形RVO碰撞体 xff0c 如果要添加自己的需要继承RVOObstacle抽象类 xff0c 重写里面的方法 例如下面的圆柱形碰撞 using UnityEngine if UNITY EDITOR using UnityEd
  • Android中抓取手机视频流数据。

    目前实时抓取手机视频数据有2种方法 xff0c 一种是通过camera的回调获取源数据 xff0c 这里获取的源数据是没有编码的数据 有的人发送yuv数据然后在那绘制图片 xff0c 也说视频聊天 xff0c 真是可笑 这种方式是可是实现视