如何从我的 Android 设备直接在 Helix 服务器上录制视频?

Posted

技术标签:

【中文标题】如何从我的 Android 设备直接在 Helix 服务器上录制视频?【英文标题】:How to record a video directly on Helix Server from my Android device? 【发布时间】:2013-02-12 19:25:08 【问题描述】:

我是服务器端开发的新手。我想在一个应用程序上工作,我需要通过我的应用程序从我的 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 服务器上? 我应该在服务器端开发上做任何实现吗?

【问题讨论】:

【参考方案1】:

在给定的时间间隔内,视频大小与网络上传容量之间的比率很低,无法同时上传/录制视频流,除非用户具有非常快的 LTE 蜂窝连接。

但是,录制完成后,您可以通过 FTP 协议将文件上传到您的服务器。建议给每个录制的文件一个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 服务器

我在simplehelix.com 上找到了这个关于How to Manage and Use FTP 的教程,以及这个视频Windows Server 2008 R2 - Configuring an FTP Server。您只需按照说明操作,但跳过称为登录 FTP 帐户的步骤,因为它仅说明如何从应用程序客户端(如 FileZilla 或 CuteFTP)管理文件)。这用我上面写的Java sn-p 完成的。另外,如果对你有帮助,我找到了this video。

注意:在第一个代码(Java)中,除非您的 FTP 服务器访问的根目录是包含所有媒体文件的文件夹,否则您将必须替换sb.append("/"); 可流媒体文件所在/应该位于的文件夹的路径。表单示例,sb.append("/username/media/");

【讨论】:

我应该说Atom能上github真是太酷了!和 +1【参考方案2】:

正如@guillaume 所说,解决此问题的最佳方法是使用 FTP 协议将记录的文件从您的设备上传到您的数据库。

我做了一个类似的项目,其中 Android 设备需要访问远程数据库。这是通过使用 android 系统中的 HTTP 协议实现的。本教程真正分解并概述了如何编写 PHP 脚本,HTTP 协议如何在 android 中工作,以及脚本如何与远程数据库一起工作:

http://blog.sptechnolab.com/2011/02/10/android/android-connecting-to-mysql-using-php/

【讨论】:

我正在寻找如何使用 helix server 来实现它 Prasad,我还没有机会使用 helix 服务器,但是这个关于使用 Helix 通用服务器中继广播的讨论讨论了在客户端使用编码器并将其配置为指向 helix服务器:helixforum.realnetworks.com/helix_support/topics/…您也可以查看开源 Red5 媒体服务器,并将移动应用程序视为另一种解决方案:red5.org

以上是关于如何从我的 Android 设备直接在 Helix 服务器上录制视频?的主要内容,如果未能解决你的问题,请参考以下文章

如何从我的 Android 设备访问我的本地主机

如何从我的 android 设备访问我的本地 REST api?

从 helix 服务器中删除文件和文件夹,同时将它们保留在 pc 上

如何直接从我的 Android 应用程序打开 Amazon AppStore?

如何在 android 中远程更新我的 cordova/phonegap 移动应用程序?

如何确保可以从我的设备网络访问 GCM 服务器?