我是服务器端开发的新手。我想在一个应用程序上工作,我需要通过我的应用程序从我的 Android 设备在 Helix 服务器上录制视频。我在 Windows Server PC 上安装了 Helix Server。
在 Android 应用程序中,我正在尝试将录制的视频上传到 Helix 服务器。我已经实现了在 SD 卡上录制视频的应用程序,但我想直接在 Helix Server 上录制并保存该视频。我已按如下方式实现了我的 Android 应用程序:
public class NewRecordingVideo extends Activity implements SurfaceHolder.Callback {
private MediaRecorder recorder;
boolean flag = false;
boolean startedRecording = false;
boolean stoppedRecording = false;
SurfaceHolder mHolder;
SurfaceView videoSView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.activity_main);
recorder = new MediaRecorder();
recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_RECOGNITION);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
videoSView = ((SurfaceView)findViewById(R.id.surfaceView1));
mHolder=videoSView.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
((Button)findViewById(R.id.startBtn)).setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View arg0) {
if(startedRecording == false) {
recorder.start();
startedRecording = true;
Toast.makeText(NewRecordingVideo.this,
"Your video is recording", Toast.LENGTH_LONG).show();
} else if (startedRecording == true && stoppedRecording == false) {
recorder.stop();
recorder.release();
recorder = null;
stoppedRecording = true;
}
}
});
((Button)findViewById(R.id.stopBtn)).setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
recorder.stop();
recorder.release();
recorder = null;
stoppedRecording = true;
Toast.makeText(NewRecordingVideo.this,
"Your video recorded ", Toast.LENGTH_LONG).show();
finish();
}
});
}
public Surface getSurface() {
return mHolder.getSurface();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
Socket socket = new Socket("IP address", 8008);
ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);
Log.v("find about connection","====>"+socket.isConnected());
recorder.setOutputFile("/sdcard/recording.3gp");
// Here I would like to record my video (recording.3gp) on helix server directly
recorder.setPreviewDisplay(mHolder.getSurface());
recorder.prepare();
} catch (Exception e) {
String message = e.getMessage();
recorder.release();
recorder = null;
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (recorder != null) {
recorder.release();
recorder = null;
}
}
}
从上面的代码:如何将我的视频录制文件直接保存在 Helix 服务器上? 我应该在服务器端开发上做任何实现吗?
最佳答案
在给定的时间间隔内,视频大小与网络上传容量之间的比率很低,无法同时上传/录制视频流,除非用户具有非常快的 LTE 蜂窝连接。
但是,录制完成后,您可以通过 FTP 协议(protocol)将文件上传到您的服务器。建议给每个录制的文件一个 Universal Unique Identifier (UUID)
以便能够区分所有其他录制的文件。我使用了这段代码(未针对 Android 进行测试,但在 JavaSE 7 上运行良好)。由于这是一个相当长(但很快)的过程,我给你做了一个总结。 (不错吧?)
总结
1) 用UUID.randomUUID().toString();
生成一个UUID,在整个过程中用来识别录制的文件。
2) 记录文件名为"sdcard/"+ uuid + ".3gp"
3) 录制结束后,通过FTP上传文件到您的服务器。
4)命令你的远程服务器执行PHP脚本,对记录的文件做任何它需要做的事情,比如数据库操作等(如果有这样的脚本,如果你不需要这样做,跳过这个步骤)。
5) 如果需要,命令您的远程服务器删除文件。 (通过另一个 PHP 脚本完成)
代码
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
public class FTPUploader {
static void doUpload(String uuid) {
File fileSource = new File("/sdcard/" + uuid + ".3gp");
// Or new File("/sdcard/recording.3gp");
String fileName = fileSource.getName();
/** YOUR SERVER'S INFORMATIONS **/
String userName = "USERNAME";
String password = "PASSWORD";
String ftpServer = "FTP.SERVER.COM";
/****/
StringBuffer sb = new StringBuffer("ftp://");
sb.append(userName);
sb.append(':');
sb.append(password);
sb.append('@');
sb.append(ftpServer);
sb.append("/");
/**WARNING: Path extension; it will be added after connection
*The file must be at your server's root. Otherwise the PHP script won't detect it.
**/
sb.append(fileName);
sb.append(";type=i");
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
URL url = new URL(sb.toString());
URLConnection urlc = url.openConnection();
bos = new BufferedOutputStream(urlc.getOutputStream());
bis = new BufferedInputStream(new FileInputStream(fileSource));
int i;
// read byte by byte until end of stream
while ((i = bis.read()) != -1) {
bos.write(i);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bis != null)
try {
bis.close();
} catch (IOException ioe) {
ioe.printStackTrace();
System.out.println("IO exception after if bis " + ioe);
}
if (bos != null)
try {
bos.close();
} catch (IOException ioe) {
ioe.printStackTrace();
System.out.println("IO exception after if " + ioe);
}
}
}
}
import java.util.UUID;
public class Main {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String uuid = UUID.randomUUID().toString();
//Assuming you set your file's name as uuid + ".3gp"
FTPUploader.doUpload(uuid);
//Launches a FTP Upload
//Then, if you want to ask your server to "process" the file you gave him, you can perform a simple HTTP request:
try {
String url = "http://YOURSITE.COM/shell.php";
String charset = "iso-8859-1";
String param1 = uuid;
String query = String.format("id=%s", URLEncoder.encode(param1, charset));
URLConnection connection = new URL(url + "?" + query).openConnection();
connection.setRequestProperty("Accept-Charset", charset);
connection.getInputStream();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//This try {}catch{} requests a PHP script: this script is "triggered" just like if it was loaded in your web browser, with as parameter the file UUID (`shell.php?id=UUID`), so that he knows wich file on his server he has to process.
}
奖励:如果您想在完成后从服务器中删除文件,您可以执行与之前相同的行,但将“shell.php”替换为另一个 PHP 脚本你可以调用“delete.php”。它将包含以下几行:
<?php
$recordedFile = $_GET['id'] . ".3gp";
unlink($recordedFile);
?>
例如:以下请求 http://www.YOURSERVER.com/delete.php?id=123456789
删除 http://www.YOURSERVER.com/123456789.3gp
在您的服务器上。
另一个示例代码
几周前,我建立了一个 Java 应用程序(我称之为 Atom...),它可以分析语音并回答所有问题(使用 Google(非官方)语音识别 API 和 Wolfram|Alpha API)。你绝对应该 take a look at it on GitHub ,所有使用的文件,包括桌面端和服务器端。希望我有所帮助!
编辑:使用您的 Helix 服务器
我在 How to Manage and Use FTP 上找到了这个关于 simplehelix.com 的教程,以及这个视频 Windows Server 2008 R2 - Configuring an FTP Server。您只需按照说明操作,但跳过称为登录 FTP 帐户的步骤,因为它仅说明如何从应用程序客户端(如 FileZilla 或 CuteFTP)管理文件)。这是用我上面写的Java代码 fragment 完成的。另外,如果它可以帮助你,我找到了 this video 。
注意:在第一个代码(Java)中,除非您的 FTP 服务器访问的根目录是包含所有媒体文件的文件夹,否则您将必须替换sb.append("/");
可流媒体文件所在/应该所在的文件夹的路径。表单示例,sb.append("/username/media/");
.
关于android - 如何从我的 Android 设备直接在 Helix 服务器上录制视频?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15104451/