Google Glass прямой эфир видео с использованием RTSP-сервера Wowza

Я пытаюсь создать приложение Google Glass, которое поддерживает потоковую трансляцию. Знаю, что для этого доступно приложение Livestream, но я не думаю, что мы можем интегрировать его в наше приложение, или я ошибаюсь? Есть ли способ интегрировать прямую трансляцию в наше приложение?

Я наткнулся на этот https://github.com/andermaco/GlassStream проект с открытым исходным кодом, который делает то же самое, используя RTSP-сервер Wowza. В соответствии с инструкциями я дал имя пользователя / пароль и обновил URL. Но во время работы есть проблема при запуске приложения. Я пытался отладить его, но не удалось. Это журнал получаю неоднократно

исключение.java:88) на java.lang.Thread.run(Thread.java:841)

Некоторые пользователи использовали и успешно работают. Пожалуйста, поделитесь со мной исходным кодом или дайте мне знать, если что-то не так в настройке сервера. Даже если есть какой-то другой ресурс для реализации, это было бы здорово.

Заранее спасибо.

1 ответ

Этот код я использовал, чтобы заставить его работать на Google Glass (XE22), используя медиа-сервер Wowza и libstreaming.

У меня два класса AppConfig а также MyActivity,

AppConfig:

package com.example.GlassApp;

/**
 * User: Colin Shewell
 * Date: 21/08/14
 * Time: 15:30
 */
public class AppConfig {
  public static final String STREAM_URL = "rtsp://193.61.148.73:1935/serg/android_test";
  //public static final String STREAM_URL = "rtsp://192.168.2.2:1935/serg/android_test";
  public static final String PUBLISHER_USERNAME = "";
  public static final String PUBLISHER_PASSWORD = "";
}

MyActivity:

    package com.example.GlassApp;

/**
 * User: Colin Shewell
 * Date: 21/08/14
 * Time: 15:30
 */
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    import net.majorkernelpanic.streaming.Session;
    import net.majorkernelpanic.streaming.SessionBuilder;
    import net.majorkernelpanic.streaming.audio.AudioQuality;
    import net.majorkernelpanic.streaming.gl.SurfaceView;
    import net.majorkernelpanic.streaming.rtsp.RtspClient;
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.content.DialogInterface;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.SurfaceHolder;
    import android.view.Window;
    import android.view.WindowManager;
    import net.majorkernelpanic.streaming.video.VideoQuality;

    public class MyActivity extends Activity implements RtspClient.Callback, Session.Callback, SurfaceHolder.Callback {
      // log tag
      public final static String TAG = MyActivity.class.getSimpleName();

      // surfaceview
      private static SurfaceView mSurfaceView;

      // Rtsp session
      private Session mSession;
      private static RtspClient mClient;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        // getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.activity_main);

        mSurfaceView = (SurfaceView) findViewById(R.id.surface);

        mSurfaceView.getHolder().addCallback(this);

        // Initialize RTSP client
        initRtspClient();
      }

      @Override
      protected void onResume() {
        super.onResume();

        toggleStreaming();
      }

      @Override
      protected void onPause(){
        super.onPause();

        toggleStreaming();
      }

      private void initRtspClient() {
        // Configures the SessionBuilder
        mSession = SessionBuilder.getInstance()
            .setContext(getApplicationContext())
            .setAudioEncoder(SessionBuilder.AUDIO_NONE)
            .setVideoEncoder(SessionBuilder.VIDEO_H264)
            .setVideoQuality(new VideoQuality(640, 480, 20, 500000)) //only need if you want to change the resolution from default
            .setSurfaceView(mSurfaceView).setPreviewOrientation(0)
            .setCallback(this).build();

        // Configures the RTSP client
        mClient = new RtspClient();
        mClient.setSession(mSession);
        mClient.setCallback(this);
        mSurfaceView.setAspectRatioMode(SurfaceView.ASPECT_RATIO_PREVIEW);
        String ip, port, path;

        // We parse the URI written in the Editext
        Pattern uri = Pattern.compile("rtsp://(.+):(\\d+)/(.+)");  
        Matcher m = uri.matcher(AppConfig.STREAM_URL);
        m.find();
        ip = m.group(1);
        port = m.group(2);
        path = m.group(3);

        mClient.setCredentials(AppConfig.PUBLISHER_USERNAME,
            AppConfig.PUBLISHER_PASSWORD);
        mClient.setServerAddress(ip, Integer.parseInt(port));
        mClient.setStreamPath("/" + path);
      }

      private void toggleStreaming() {
        if (!mClient.isStreaming()) {
          // Start camera preview
          mSession.startPreview();

          // Start video stream
          mClient.startStream();
        } else {
          // already streaming, stop streaming
          // stop camera preview
          mSession.stopPreview();

          // stop streaming
          mClient.stopStream();
        }
      }

      @Override
      public void onDestroy() {
        super.onDestroy();
        mClient.release();
        mSession.release();
        mSurfaceView.getHolder().removeCallback(this);
      }

      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
      }

      @Override
      public void onSessionError(int reason, int streamType, Exception e) {
        switch (reason) {
          case Session.ERROR_CAMERA_ALREADY_IN_USE:
            break;
          case Session.ERROR_CAMERA_HAS_NO_FLASH:
            break;
          case Session.ERROR_INVALID_SURFACE:
            break;
          case Session.ERROR_STORAGE_NOT_READY:
            break;
          case Session.ERROR_CONFIGURATION_NOT_SUPPORTED:
            break;
          case Session.ERROR_OTHER:
            break;
        }

        if (e != null) {
          alertError(e.getMessage());
          e.printStackTrace();
        }
      }

      private void alertError(final String msg) {
        final String error = (msg == null) ? "Unknown error: " : msg;
        AlertDialog.Builder builder = new AlertDialog.Builder(MyActivity.this);
        builder.setMessage(error).setPositiveButton("Ok",
            new DialogInterface.OnClickListener() {
              public void onClick(DialogInterface dialog, int id) {
              }
            });
        AlertDialog dialog = builder.create();
        dialog.show();
      }

      @Override
      public void onRtspUpdate(int message, Exception exception) {
        switch (message) {
          case RtspClient.ERROR_CONNECTION_FAILED:
          case RtspClient.ERROR_WRONG_CREDENTIALS:
            alertError(exception.getMessage());
            exception.printStackTrace();
            break;
        }
      }

      @Override
      public void onPreviewStarted() {
      }

      @Override
      public void onSessionConfigured() {
      }

      @Override
      public void onSessionStarted() {
      }

      @Override
      public void onSessionStopped() {
      }

      @Override
      public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
      }

      @Override
      public void surfaceCreated(SurfaceHolder holder) {
      }

      @Override
      public void surfaceDestroyed(SurfaceHolder holder) {
      }

      // @Override
      public void onBitrateUpdate(long bitrate) {
      }
    }

РЕДАКТИРОВАТЬ: Я могу подтвердить, что следующие настройки качества видео работают:

.setVideoQuality(new VideoQuality(640, 480, 20, 500000))
.setVideoQuality(new VideoQuality(960, 720, 20, 500000))

Я также хотел бы добавить, что при значении fps, превышающем 20, приложение не запускается.

Другие вопросы по тегам