已经过了一个月,我现在失去了希望。
我正在尝试从设备1捕获视频并将其流式传输到设备2.
我已经可以保存视频文件,但问题是我在设备1使用相机拍摄视频时同时将其流式传输到另一部手机。
我已经看过很多有关流媒体视频的教程并在我的视频中应用,但视频已经保存在设备中,而不是同时捕获和流式传输。
我希望你能帮助我。
UPDATE .............................................. ..................
目前我可以通过socket发送文本。我只是将图像捕获包含在那里以测试保存手机中的数据,但它还没有通过套接字发送它。
这是我现在的代码:
CameraActivity.Java(既用作服务器又用于捕获数据的那个)
package com.example.martinlloydjose.shaveyourback;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
//import android.graphics.Camera;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.provider.MediaStore.Files.FileColumns;
//import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.os.Bundle;
import android.widget.Toast;
import static android.content.ContentValues.TAG;
import static android.provider.MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE;
public class CameraActivity extends AppCompatActivity{
//camera --------------------------------------------------------------------------------------------
/*camera
private static final int CAMERA_REQUEST = 1888;
private ImageView imageView;
*/
private Camera mCamera;
private SurfaceView mPreview;
private MediaRecorder mMediaRecorder;
//end of camera --------------------------------------------------------------------------------------------
//server ////////////////////////////////////////////////////////////////////////////////////////////
EditText welcomeMsg;
TextView infoIp;
TextView infoMsg;
String msgLog = "";
ServerSocket httpServerSocket;
//end of server ////////////////////////////////////////////////////////////////////////////////////////////
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
//camera --------------------------------------------------------------------------------------------
/*
this.imageView = (ImageView)this.findViewById(R.id.imageView1);
Button photoButton = (Button) this.findViewById(R.id.button1);
photoButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
});
*/
// Create an instance of Camera
/** Showing current image */
try {
new AlertDialog.Builder(this).setTitle("Test").setMessage("Running").setNeutralButton("Close", null).show();
mCamera = getCameraInstance();
mCamera.setDisplayOrientation(90);
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
}catch (Exception error){
Toast.makeText(this, "An error occured with your camera: "+error.toString(), Toast.LENGTH_LONG).show();
}
/** end of Showing current image */
/** Capturing Image */
try {
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
}
);
}catch (Exception error){
Toast.makeText(this, "An error occured with your camera: "+error.toString(), Toast.LENGTH_LONG).show();
}
/** end of Capturing Image */
//end of camera --------------------------------------------------------------------------------------------
//server ////////////////////////////////////////////////////////////////////////////////////////////
welcomeMsg = (EditText) findViewById(R.id.welcomemsg);
infoIp = (TextView) findViewById(R.id.infoip);
infoMsg = (TextView) findViewById(R.id.msg);
infoIp.setText(getIpAddress() + ":" + HttpServerThread.HttpServerPORT + "\n");
HttpServerThread httpServerThread = new HttpServerThread();
httpServerThread.start();
//end of server ////////////////////////////////////////////////////////////////////////////////////////////
}
//camera --------------------------------------------------------------------------------------------
/*
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
imageView.setImageBitmap(photo);
}
}
*/
/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
/** end of Check if this device has a camera */
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
/** end of A safe way to get an instance of the Camera object. */
/** Capture Pictures */
private PictureCallback mPicture = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: "
/*e.getMessage()*/);
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
/** end of Capture Pictures */
/** Setting the storage */
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
/** end of Setting the storage */
/** releasing camera */
@Override
protected void onPause() {
super.onPause();
//releaseMediaRecorder(); // if you are using MediaRecorder, release it first
releaseCamera(); // release the camera immediately on pause event
}
/*private void releaseMediaRecorder(){
if (mMediaRecorder != null) {
mMediaRecorder.reset(); // clear recorder configuration
mMediaRecorder.release(); // release the recorder object
mMediaRecorder = null;
mCamera.lock(); // lock camera for later use
}
}*/
private void releaseCamera(){
if (mCamera != null){
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
/** end of releasing camera */
//end of camera --------------------------------------------------------------------------------------------
//server -001 ////////////////////////////////////////////////////////////////////////////////////////////
@Override
protected void onDestroy() {
super.onDestroy();
if (httpServerSocket != null) {
try {
httpServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private String getIpAddress() {
String ip = "";
try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces
.nextElement();
Enumeration<InetAddress> enumInetAddress = networkInterface
.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();
if (inetAddress.isSiteLocalAddress()) {
ip += "SiteLocalAddress: "
+ inetAddress.getHostAddress() + "\n";
}
}
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n" +e.getMessage();
}
return ip;
}
private class HttpServerThread extends Thread {
static final int HttpServerPORT = 8888;
@Override
public void run() {
Socket socket = null;
try {
httpServerSocket = new ServerSocket(HttpServerPORT);
while(true){
socket = httpServerSocket.accept();
HttpResponseThread httpResponseThread =
new HttpResponseThread(
socket,
welcomeMsg.getText().toString());
httpResponseThread.start();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class HttpResponseThread extends Thread {
Socket socket;
String h1;
HttpResponseThread(Socket socket, String msg){
this.socket = socket;
h1 = msg;
}
@Override
public void run() {
BufferedReader is;
PrintWriter os;
String request;
try {
is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
request = is.readLine();
os = new PrintWriter(socket.getOutputStream(), true);
String response =
"<html><head></head>" +
"<body>" +
"<h1>" + h1 + "</h1>" +
"</body></html>";
os.print("HTTP/1.0 200" + "\r\n");
os.print("Content type: text/html" + "\r\n");
os.print("Content length: " + response.length() + "\r\n");
os.print("\r\n");
os.print(response + "\r\n");
os.flush();
socket.close();
msgLog += "Request of " + request
+ " from " + socket.getInetAddress().toString() + "\n";
CameraActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
infoMsg.setText(msgLog);
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return;
}
}
//end of server -001 ////////////////////////////////////////////////////////////////////////////////////////////
}
ViewerActivity.java
package com.example.martinlloydjose.shaveyourback;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.WebView;
public class ViewerActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_viewer);
WebView webView = (WebView)findViewById(R.id.webViewStream);
webView.loadUrl("http://10.0.2.15:8888");
webView.getSettings().setBuiltInZoomControls(true);
}
}
Activity_Camera.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="0dp"
android:paddingRight="0dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
tools:context="com.example.martinlloydjose.shaveyourback.CameraActivity">
<TextView
android:id="@+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Connect using the following details"
android:textStyle="bold" />
<EditText
android:id="@+id/welcomemsg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Test Message"
android:layout_below="@+id/tvTitle"
/>
<TextView
android:id="@+id/infoip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/welcomemsg"
/>
<ScrollView
android:id="@+id/scrollSlider"
android:layout_width="match_parent"
android:layout_height="100sp"
android:layout_below="@+id/infoip">
<TextView
android:id="@+id/msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</ScrollView>
<!--
<ImageView
android:id="@+id/imageView1"
android:layout_height="fill_parent"
android:src="@drawable/icon"
android:layout_width="fill_parent"
android:layout_below="@+id/scrollSlider"
>
</ImageView>
<Button
android:id="@+id/button1"
android:layout_below="@id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="-50sp"
android:text="capture">
</Button>
-->
<FrameLayout
android:id="@+id/camera_preview"
android:layout_below="@+id/scrollSlider"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
/>
<Button
android:id="@+id/button_capture"
android:text="Capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_below="@+id/camera_preview"
android:layout_centerHorizontal="true"
android:layout_marginTop="-50sp"
/>
</RelativeLayout>
Activity_Viewer.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="0dp"
android:paddingRight="0dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
tools:context="com.example.martinlloydjose.shaveyourback.ViewerActivity">
<WebView
android:id="@+id/webViewStream"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="0dp"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp" />
</RelativeLayout>
答案 0 :(得分:0)
我假设你已经有一台服务器作为中介。在这种情况下,您可以设置NGINX服务器环境并在其上安装nginx-rtmp-module。此外,您还可以使用SRS实时流式集群,它还可以创建自己的服务器环境。
因为它们都是开源的,所以它们具有成本效益。
此外,srs 3.0比nginx-rtmp-module更加先进,因为它具有大量的功能。但是对于简单的流媒体,我认为是你的情况,两者都同样有用,但我会建议nginx-rtmo-module,因为nginx的强大功能。
这涵盖了服务器创建的所有内容。之后,您可以在Android上使用vlc,或者从github使用任何rtmp流式回购来进行流式传输。为了接收您的流,大多数主要视频播放器支持直播。所以你只需要输入你的流媒体rtmp:// ....地址。
以下是一些参考文献,虽然它们已经过时,但核心仍然是相同的。