ImageVerifierCode 换一换
格式:DOCX , 页数:30 ,大小:815.75KB ,
资源ID:5040426      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/5040426.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(最纯粹的直播技术实战02Camera的处理以及推流.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

最纯粹的直播技术实战02Camera的处理以及推流.docx

1、最纯粹的直播技术实战02Camera的处理以及推流最纯粹的直播技术实战02-Camera的处理以及推流我们在MainActivity里面添加两个Button,一个是直播的,一个是看直播的android:id=+id/activity_main android:layout_width=match_parent android:layout_height=match_parent android:paddingBottom=dimen/activity_vertical_margin android:paddingLeft=dimen/activity_horizontal_margin and

2、roid:paddingRight=dimen/activity_horizontal_margin android:paddingTop=dimen/activity_vertical_margin android:orientation=vertical tools:context=com.xiaoxiao.live.MainActivity 我们把上一次的测试TextView注释掉了,然后新建了一个LiveActivity来处理Camera以及推流,主要就是展示直播。 后续还会有看直播的处理,就要就是拉流以及视频的播放了 接下来就要在LiveActivity里面处理一下Camera的东西

3、了,首先要在LiveActivity的layout里面添加一个SurfaceViewandroid:orientation=vertical android:layout_width=match_parent android:layout_height=match_parent 因为不是拍照,所以Camera的处理就会显得比较的简单了,package com.xiaoxiao.live;import android.graphics.ImageFormat;import android.hardware.Camera;import android.os.Bundle;import androi

4、d.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.SurfaceHolder;import android.view.SurfaceView;/* * Created by Administrator on 2017/2/20. */public class LiveActivity extends AppCompatActivity implements SurfaceHolde

5、r.Callback, Camera.PreviewCallback private Camera mCamera; private SurfaceView mSurfaceView; private SurfaceHolder mSurfaceHolder; private int mCameraId = 0; private int width = 720; private int height = 480; Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState)

6、; setContentView(R.layout.activity_live); mSurfaceView = (SurfaceView) findViewById(R.id.live_sv_live); mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.setFixedSize(width, height); mSurfaceHolder.addCallback(this); Override public boolean onCreateOptionsMenu(Menu menu) getMenuInflater().in

7、flate(R.menu.menu_live, menu); return true; Override public boolean onOptionsItemSelected(MenuItem item) if(item.getItemId() = R.id.checkable_menu) boolean isChecked = item.isChecked(); Log.e(LiveActivity, checked: + isChecked); item.setChecked(!isChecked); mCameraId = 1 - mCameraId; destroyCamera()

8、; initCamera(); return true; return super.onOptionsItemSelected(item); Override public void onPreviewFrame(byte data, Camera camera) Override public void surfaceCreated(SurfaceHolder holder) initCamera(); Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) Ov

9、erride public void surfaceDestroyed(SurfaceHolder holder) destroyCamera(); private void initCamera() try mCamera = Camera.open(mCameraId); mCamera.setPreviewDisplay(mSurfaceHolder); Camera.Parameters params = mCamera.getParameters(); /设置预览大小 params.setPreviewSize(width, height); /设置生成的照片大小 params.se

10、tPictureSize(width, height); params.setPreviewFormat(ImageFormat.NV21); mCamera.setDisplayOrientation(90); /params.setRotation(90); /*List sizes = params.getSupportedPreviewSizes(); for(Camera.Size s : sizes) Log.e(LiveActivity, s.width + X + s.height); */ mCamera.setParameters(params); mCamera.setP

11、reviewCallback(this); mCamera.startPreview(); catch (Exception e) e.printStackTrace(); private void destroyCamera() if(mCamera = null) return; mCamera.setPreviewCallback(null); mCamera.stopPreview(); mCamera.release(); mCamera = null; 我们通过menu来做了一个摄像头的切换功能,这样子就可以前摄像头直播或者后摄像头直播了。 到时会在onPreviewFrame里面

12、获取到数据,然后交给jni进行一个编码的处理,然后就推流那么这里就会有一个非常重要的知识点了: 我们通过setPreviewFormat方法把预览的数据(onPreviewFrame方法参数里面的data)的格式设置成了ImageFormat.NV21,一般来说,常用的格式是NV21或者YV12,因为这两种格式被所有的摄像头支持的,Android默认是会设置NV21的。那么什么是NV21或YV12呢,其实这也是一种yuv格式的数据来的上一篇文章我们已经说过了,就是通过把yuv通过编码,然后再封装就可以得到一个视频文件了,但我们还需要对这种yuv进行一定的处理,因为yuv也是有不同的各类的。yu

13、v通常分成两大格式,一种是planar:把所有像素点的Y值全部存放在数组的最前面,然后再存放所有像素点的U值,最后再存放所有像素点的V值 还有一种就是packed:它是依次存放每一个像素点的YUV值的同时yuv还有不同的采样方式,一般主流的有三种:YUV4:4:4 每一个Y对应一组UV分量YUV4:2:2 每两个Y共用一组UV分量YUV4:2:0 每四个Y共用一组UV分量假设一张720 X 480的图片存储成yuv格式:YUV4:4:4 Y = 720 * 480 U = V = 720 * 480 所以整个数组的大小就是720 * 480 * 3YUV4:2:2 Y = 720 * 480

14、U = V = 720 * 480 / 2 所以整个数组的大小就是720 * 480 * 2YUV4:2:0 Y = 720 * 480 U = V = 720 * 480 / 4 所以整个数组的大小就是720 * 480 * 1.5NV21和YV12就是YUV4:2:0这种采样格式的,而且我们到时用FFmpeg编码采用的格式一般是AV_PIX_FMT_YUV420P,都是YUV4:2:0这种采样格式的但还是有一些差别的AV_PIX_FMT_YUV420P 格式是planar,就是先存全部的Y再存全部的U再存全部的V,采样格式4:2:0。存储格式类似 yyyyyyyy uu vv 这样NV21

15、 格式也是planar,采样格式也是4:2:0。存储格式类似 yyyyyyyy vu vuYV12 格式也是planar,采样格式也是4:2:0。存储格式类似 yyyyyyyy vv uu从上面可以看到,我们需要用的格式和预览的格式还是有些差别的,所以我们到时要处理一下。那么现在我们可以先把我们的Camera的功能给测试一下先的,看看能不能预览成功,但在运行前,还需要去AndroidManifest里面配置一下如果Camera模块测试没有问题的话,我们就可以来写native方法了,首先在LiveActivity里面定义好几个native方法 /* * 初始化编码的一些东西,比如编码器等 * p

16、aram width 编码视频的宽 * param height 编码视频的高 * return 0 成功 小于0失败 */ private native int streamerInit(int width, int height); /* * 对每一次预览的数据进行编码推流 * param data NV21格式的数据 * return 0成功,小于0失败 */ private native int streamerHandle(byte data); /* * 把缓冲帧的数据清空 * return 0成功,小于0失败 */ private native int streamerFlush

17、(); /* * 释放资源,比如编码器这些 * return 0成功,小于0失败 */private native int streamerRelease();定义完成native方法后,我们先把LiveActivity里面的逻辑给处理一下先。为了不影响UI线程(以后可能数据处理会有点多),我就使用了HandlerThread这个类来进行异步操作,先把类初始化 mHandlerThread = new HandlerThread(liveHandlerThread); mHandlerThread.start(); mHandler = new LiveHandler(this, mHandl

18、erThread.getLooper();LiveHandler是我定义在LiveActivity的静态内部类,用来进行异步操作的 private static class LiveHandler extends Handler private WeakReference mActivity; public LiveHandler(LiveActivity activity, Looper looper) super(looper); mActivity = new WeakReference(activity); Override public void handleMessage(Mess

19、age msg) super.handleMessage(msg); LiveActivity activity = mActivity.get(); if(activity = null) return; switch (msg.what) case STREAMER_INIT: break; case STREAMER_HANDLE: Bundle bundle = msg.getData(); if(bundle != null) byte data = bundle.getByteArray(frame_data); if(data != null & data.length 0) a

20、ctivity.streamerHandle(data); else Log.e(LiveActivity, byte data null); else Log.e(LiveActivity, bundle null); break; case STREAMER_FLUSH: activity.streamerFlush(); break; case STREAMER_RELEASE: activity.streamerRelease(); break; LiveActivity里面的逻辑主要是一些细节的处理,完整的代码就下面那样:package com.xiaoxiao.live;impor

21、t android.graphics.ImageFormat;import android.hardware.Camera;import android.os.Bundle;import android.os.Handler;import android.os.HandlerThread;import android.os.Looper;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.Menu;import

22、android.view.MenuItem;import android.view.SurfaceHolder;import android.view.SurfaceView;import java.lang.ref.WeakReference;/* * Created by Administrator on 2017/2/20. */public class LiveActivity extends AppCompatActivity implements SurfaceHolder.Callback, Camera.PreviewCallback private static final

23、int STREAMER_INIT = 0; private static final int STREAMER_HANDLE = 1; private static final int STREAMER_RELEASE = 2; private static final int STREAMER_FLUSH = 3; private Camera mCamera; private SurfaceView mSurfaceView; private SurfaceHolder mSurfaceHolder; private int mCameraId = 0; private int widt

24、h = 720; private int height = 480; /* * 判断有没有初始化成功,不成功不不进行后续的编码处理 */ private int liveInitResult = -1; /* * 异步操作 */ private HandlerThread mHandlerThread; private LiveHandler mHandler; Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.

25、activity_live); mSurfaceView = (SurfaceView) findViewById(R.id.live_sv_live); mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.setFixedSize(width, height); mSurfaceHolder.addCallback(this); mHandlerThread = new HandlerThread(liveHandlerThread); mHandlerThread.start(); mHandler = new LiveHan

26、dler(this, mHandlerThread.getLooper(); Override public boolean onCreateOptionsMenu(Menu menu) getMenuInflater().inflate(R.menu.menu_live, menu); return true; Override public boolean onOptionsItemSelected(MenuItem item) if(item.getItemId() = R.id.checkable_menu) boolean isChecked = item.isChecked();

27、Log.e(LiveActivity, checked: + isChecked); item.setChecked(!isChecked); mCameraId = 1 - mCameraId; destroyCamera(); initCamera(); return true; return super.onOptionsItemSelected(item); Override public void onPreviewFrame(byte data, Camera camera) /* * 如果初始化成功,那就把数据发送到Handler,然后再调用native方法 */ if(live

28、InitResult = 0 & data != null & data.length 0) Message msg = Message.obtain(); Bundle bundle = new Bundle(); bundle.putByteArray(frame_data, data); msg.what = STREAMER_HANDLE; msg.setData(bundle); mHandler.sendMessage(msg); Override public void surfaceCreated(SurfaceHolder holder) /* * 在surface创建的时候进行初始化,如果失败了,也是需要释放已经开辟了

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1