ivideochat源码中关于视频通信中没有声音的问题

一颗大葱 一颗大葱 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
最近在弄android视频通话方面的东西,通过几天的研究,把一些东西都写出来,还有一些问题希望能和大家一起讨论下,我先把代码发上来,
这是videoActivity:
package net.john.activity;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Map;

import com.shouyanwang.h264encoder;
import com.smaxe.io.ByteArray;
import com.smaxe.uv.client.INetStream;
import com.smaxe.uv.client.NetStream;
import com.smaxe.uv.client.camera.AbstractCamera;
import com.smaxe.uv.stream.support.MediaDataByteArray;

import net.john.R;
import net.john.data.User;
import net.john.util.RTMPConnectionUtil;
import net.john.util.RemoteUtil;
import net.john.util.UltraNetStream;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;

public class VideoActivity extends Activity{

final String TAG = "VideoActivity";

private boolean active;
public static AndroidCamera aCamera;
private h264encoder mH264encoder;
private long handle;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//the window without title
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.layout_chat);
mH264encoder = new h264encoder();
aCamera = new AndroidCamera(VideoActivity.this);
active = true;
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {

if (keyCode == KeyEvent.KEYCODE_BACK) {
new AlertDialog.Builder(VideoActivity.this)
.setMessage(R.string.dialog_exit)
.setPositiveButton(R.string.dialog_ok, new DialogInterface.OnClickListener() {


public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
active = false;
finish();
}
})
.setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener() {


public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
dialog.dismiss();
}
}).show();
return true;
} else {
return super.onKeyDown(keyCode, event);
}
}

@Override
public void onStop() {
super.onStop();
aCamera = null;
if (RTMPConnectionUtil.netStream != null) {
RTMPConnectionUtil.netStream.close();
}

Log.d("DEBUG", "onStop");
}

@Override
public void onDestroy() {
super.onDestroy();

Log.d("DEBUG", "onDestroy()");
}

//Camera.PreviewCallback获取到camera读取的字节数组
public class AndroidCamera extends AbstractCamera implements SurfaceHolder.Callback,
Camera.PreviewCallback {

private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private Camera camera;

private int width;
private int height;

private boolean init;

int blockWidth;
int blockHeight;
int timeBetweenFrames; // 1000 / frameRate
int frameCounter;
byte[] previous;

public AndroidCamera(Context context) {


surfaceView = (SurfaceView)((Activity) context).findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(AndroidCamera.this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
//我修改过的分辨率
width = 176;
height = 144;

handle = mH264encoder.initEncoder(width, height);

init = false;
Log.d("DEBUG", "AndroidCamera()");
}

private void startVideo() {
Log.d("DEBUG", "startVideo()");

RTMPConnectionUtil.netStream = new UltraNetStream(RTMPConnectionUtil.connection);
RTMPConnectionUtil.netStream.addEventListener(new NetStream.ListenerAdapter() {

@Override
public void onNetStatus(final INetStream source, final Map<String, Object> info){
Log.d("DEBUG", "Publisher#NetStream#onNetStatus: " + info);

final Object code = info.get("code");

if (NetStream.PUBLISH_START.equals(code)) {
if (VideoActivity.aCamera != null) {
RTMPConnectionUtil.netStream.attachCamera(aCamera, -1 /*snapshotMilliseconds*/);
Log.d("DEBUG", "aCamera.start()");
aCamera.start();
} else {
Log.d("DEBUG", "camera == null");
}
}
}
});

RTMPConnectionUtil.netStream.publish("aaa", NetStream.RECORD);
}

public void start() {
camera.startPreview();
}

public void printHexString(byte[] b) {
for (int i = 0; i < b.length; i++) {
String hex = Integer.toHexString(b[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
}
}


public void onPreviewFrame(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
if (!active) return;
if (!init) {
blockWidth = 32;
blockHeight = 32;
timeBetweenFrames = 100; // 1000 / frameRate
frameCounter = 0;
previous = null;
init = true;
}
final long ctime = System.currentTimeMillis();
Log.i(TAG, "*****相机采集到的数组长度"+arg0.length);

byte[] current = RemoteUtil.decodeYUV420SP2RGB(arg0, width, height);
try {
// int byte_result = Decode(arg0);
// byte[] bytes1 = copyOf(out,byte_result);
//fireOnVideoData
final byte[] packet = RemoteUtil.encode(current, previous, blockWidth, blockHeight, width, height);
fireOnVideoData(new MediaDataByteArray(timeBetweenFrames, new ByteArray(packet)));
previous = current;
if (++frameCounter % 10 == 0) previous = null;

}
catch (Exception e) {
e.printStackTrace();
}
final int spent = (int) (System.currentTimeMillis() - ctime);
try {
Thread.sleep(Math.max(0, timeBetweenFrames - spent));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public byte[] copyOf(byte[] arr,int len)
{
Class type=arr.getClass().getComponentType();
byte[] target=(byte[])Array.newInstance(type, len);
System.arraycopy(arr, 0, target, 0, len);
return target;
}

private byte[] out = new byte[20*1024];
long start = 0;
long end = 0;
private int Decode(byte[] yuvData){
start = System.currentTimeMillis();
int result = mH264encoder.encodeframe(handle, -1, yuvData, yuvData.length, out);
end = System.currentTimeMillis();
Log.e(TAG, "encode result:"+result+"--encode time:"+(end-start));
if(result > 0){
try {
FileOutputStream file_out = new FileOutputStream ("/sdcard/x264_video_activity.264",true);
file_out.write(out,0,result);
file_out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
// this.setPrewDataGetHandler();
return result;
}


public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
//camera.startPreview();
//camera.unlock();
startVideo();
Log.d("DEBUG", "surfaceChanged()");
}


public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
try {
camera.setPreviewDisplay(surfaceHolder);
camera.setPreviewCallback(this);
Camera.Parameters params = camera.getParameters();
params.setPreviewSize(width, height);
camera.setParameters(params);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
camera.release();
camera = null;
}

Log.d("DEBUG", "surfaceCreated()");
}


public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
if (camera != null) {
camera.stopPreview();
camera.release();
camera = null;
}
mH264encoder.destory(handle);
Log.d("DEBUG", "surfaceDestroy()");
}

} //AndroidCamera
}

zhe
...全文

相关推荐

《模式识别与数据挖掘》配套PPT课件

《模式识别与数据挖掘》配套PPT课件

Bryan Ding

科技成果转化项目进场交易前,评估备案环节需要准备哪些材料?_8.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

BIZKEEN

人工智能通识教育(中职版)课程标准+PPT课件+部分素材+电子活页+在线考核

人工智能通识教育(中职版)课程标准+PPT课件+部分素材+电子活页+在线考核

Bryan Ding

跨境电商供应链管理(AIGC版)课件+教案+参考答案

跨境电商供应链管理(AIGC版)课件+教案+参考答案

Bryan Ding

110KV单电源电网三段式电流保护+距离继电保护整定计算说明报告(23页+6000字)

内容概要:本文是一份关于110kV单电源电网继电保护整定计算的综合性技术报告,全文共23页、约6000字,系统阐述了三段式电流保护与距离保护的设计原理及其整定计算方法。报告深入分析了电力系统在短路故障条件下的电流与阻抗特性,详细推导了电流保护Ⅰ、Ⅱ、Ⅲ段的动作范围、整定原则、灵敏度校验及时间配合机制,确保满足继电保护的选择性、速动性、灵敏性和可靠性“四性”要求。同时,针对长距离或重要输电线路,补充介绍了距离保护的阻抗整定计算方法,并可能结合Matlab进行仿真验证与辅助计算,提升整定结果的准确性与工程实用性。; 适合人群:适用于电气工程及其自动化相关专业的高年级本科生、研究生,以及从事电力系统继电保护设计、运行维护的工程技术人员;要求读者具备电力系统分析、短路计算及继电保护的基础理论知识。; 使用场景及目标:①掌握110kV单电源辐射型电网中三段式电流保护的整定流程与实际计算步骤;②理解距离保护的工作原理及其在复杂工况下的应用优势;③完成实际工程项目的保护配置与整定计算任务,或作为课程设计、毕业设计及科研课题的技术参考资料;④结合Matlab工具实现整定计算的程序化处理与动作特性仿真验证。; 阅读建议:建议读者结合《电力系统继电保护原理》等相关教材同步学习,重点研读整定公式的推导过程与典型算例的计算细节,注意区分电流保护与距离保护的适用场景与配置逻辑,有条件时应利用Matlab等工具对保护动作行为进行建模与仿真,以深化对保护协调配合机制的理解。

欢多天天写代码
评论 10
收藏 已收藏
分享
返回顶部
一颗大葱
Android 80,489 成员 91,375 内容