2016-12-20 2 views
0

Я пытаюсь создать живой поток из камеры, прикрепленной к малине pi в приложении для Android.VLC в Android-приложении ищет файл вместо http-потока

Вот код деятельности:

public class Stream extends AppCompatActivity implements IVLCVout.Callback, LibVLC.OnNativeCrashListener { 
public final static String TAG = "LibVLCAndroid/Stream"; 

//public final static String LOCATION = "com.compdigitec.libvlcandroidsample.VideoActivity.location"; 

private String mFilePath; 

// display surface 
private SurfaceView mSurface; 
private SurfaceHolder holder; 

// media player 
private LibVLC libvlc; 
private MediaPlayer mMediaPlayer = null; 
private int mVideoWidth; 
private int mVideoHeight; 
private final static int VideoSizeChanged = -1; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_stream); 

    // Receive path to play from intent 
    Intent intent = getIntent(); 
    mFilePath = "http://70.122.174.124:691"; 

    Log.d(TAG, "Playing back " + mFilePath); 

    mSurface = (SurfaceView) findViewById(R.id.surface); 
    holder = mSurface.getHolder(); 
    //holder.addCallback(this); 
} 

@Override 
public void onConfigurationChanged(Configuration newConfig) { 
    super.onConfigurationChanged(newConfig); 
    setSize(mVideoWidth, mVideoHeight); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    createPlayer(mFilePath); 
} 

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

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    releasePlayer(); 
} 

private void setSize(int width, int height) { 
    mVideoWidth = width; 
    mVideoHeight = height; 
    if (mVideoWidth * mVideoHeight <= 1) 
     return; 

    if(holder == null || mSurface == null) 
     return; 

    // get screen size 
    int w = getWindow().getDecorView().getWidth(); 
    int h = getWindow().getDecorView().getHeight(); 

    // getWindow().getDecorView() doesn't always take orientation into 
    // account, we have to correct the values 
    boolean isPortrait = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT; 
    if (w > h && isPortrait || w < h && !isPortrait) { 
     int i = w; 
     w = h; 
     h = i; 
    } 

    float videoAR = (float) mVideoWidth/(float) mVideoHeight; 
    float screenAR = (float) w/(float) h; 

    if (screenAR < videoAR) 
     h = (int) (w/videoAR); 
    else 
     w = (int) (h * videoAR); 

    // force surface buffer size 
    holder.setFixedSize(mVideoWidth, mVideoHeight); 

    // set display size 
    LayoutParams lp = mSurface.getLayoutParams(); 
    lp.width = w; 
    lp.height = h; 
    mSurface.setLayoutParams(lp); 
    mSurface.invalidate(); 
} 

private void createPlayer(String media) { 
    releasePlayer(); 
    try { 
     if (media.length() > 0) { 
      Toast toast = Toast.makeText(this, media, Toast.LENGTH_LONG); 
      toast.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 
        0); 
      toast.show(); 
     } 

     // Create LibVLC 
     // TODO: make this more robust, and sync with audio demo 
     ArrayList<String> options = new ArrayList<>(); 
     //options.add("--subsdec-encoding <encoding>"); 
     options.add("-vvv"); // verbosity 
     libvlc = new LibVLC(options); 
     libvlc.setOnNativeCrashListener(this); 
     holder.setKeepScreenOn(true); 

     // Create media player 
     mMediaPlayer = new MediaPlayer(libvlc); 
     mMediaPlayer.setEventListener(mPlayerListener); 

     // Set up video output 
     final IVLCVout vout = mMediaPlayer.getVLCVout(); 
     vout.setVideoView(mSurface); 
     //vout.setSubtitlesView(mSurfaceSubtitles); 
     vout.addCallback(this); 
     vout.attachViews(); 

     Media m = new Media(libvlc, media); 
     mMediaPlayer.setMedia(m); 
     mMediaPlayer.play(); 
    } catch (Exception e) { 
     Toast.makeText(this, "Error creating player!", Toast.LENGTH_LONG).show(); 
    } 
} 

// TODO: handle this cleaner 
private void releasePlayer() { 
    if (libvlc == null) 
     return; 
    mMediaPlayer.stop(); 
    final IVLCVout vout = mMediaPlayer.getVLCVout(); 
    vout.removeCallback(this); 
    vout.detachViews(); 
    holder = null; 
    libvlc.release(); 
    libvlc = null; 

    mVideoWidth = 0; 
    mVideoHeight = 0; 
} 

private MediaPlayer.EventListener mPlayerListener = new MyPlayerListener(this); 

@Override 
public void onNewLayout(IVLCVout vout, int width, int height, int visibleWidth, int visibleHeight, int sarNum, int sarDen) { 
    if (width * height == 0) 
     return; 

    // store video size 
    mVideoWidth = width; 
    mVideoHeight = height; 
    setSize(mVideoWidth, mVideoHeight); 
} 

@Override 
public void onHardwareAccelerationError(IVLCVout vlcVout) { 
    // Handle errors with hardware acceleration 
    Log.e(TAG, "Error with hardware acceleration"); 
    this.releasePlayer(); 
    Toast.makeText(this, "Error with hardware acceleration", Toast.LENGTH_LONG).show(); 
} 

@Override 
public void onSurfacesCreated(IVLCVout vout) { 

} 

@Override 
public void onSurfacesDestroyed(IVLCVout vout) { 

} 

private static class MyPlayerListener implements MediaPlayer.EventListener { 
    private WeakReference<Stream> mOwner; 

    public MyPlayerListener(Stream owner) { 
     mOwner = new WeakReference<>(owner); 
    } 

    @Override 
    public void onEvent(MediaPlayer.Event event) { 
     Stream player = mOwner.get(); 

     switch(event.type) { 
      case MediaPlayer.Event.EndReached: 
       Log.d(TAG, "MediaPlayerEndReached"); 
       player.releasePlayer(); 
       break; 
      case MediaPlayer.Event.Playing: 
      case MediaPlayer.Event.Paused: 
      case MediaPlayer.Event.Stopped: 
      default: 
       break; 
     } 
    } 
} 

@Override 
public void onNativeCrash() { 
    // Handle errors with hardware acceleration 
    Log.e(TAG, "Native Crash"); 
    this.releasePlayer(); 
    Toast.makeText(this, "Native Crash", Toast.LENGTH_LONG).show(); 
} 

} 

И XML:

<LinearLayout 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:baselineAligned="false" 
android:orientation="vertical" 
tools:context="rpi.rpicam.Stream" > 

<FrameLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

    <SurfaceView 
     android:id="@+id/surface" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:layout_gravity="center" /> 
</FrameLayout> 

</LinearLayout> 

Однако, когда я запустить приложение я получаю следующие ошибки в журналах:

12-20 14:23:03.790 7775-1067/rpi.rpicam E/VLC: [0000007f4a5df0b8] filesystem access: cannot open file //http://70.122.174.124:691 (No such file or directory) 
12-20 14:23:03.790 7775-1067/rpi.rpicam E/VLC: [0000007f4a5df0b8] core access: File reading failed 
12-20 14:23:03.790 7775-1067/rpi.rpicam E/VLC: [0000007f4a5df0b8] core access: VLC could not open the file "//http://70.122.174.124:691" (No such file or directory). 
12-20 14:23:03.790 7775-1067/rpi.rpicam D/VLC: [0000007f4a5df0b8] core access: no access modules matched 
12-20 14:23:03.790 7775-1067/rpi.rpicam E/VLC: [0000007f7bf759b8] core input source: cannot access file:////http%3A//70.122.174.124%3A691 
12-20 14:23:03.790 7775-1067/rpi.rpicam E/VLC: [0000007f70a3f4b8] core input: Your input can't be opened 
12-20 14:23:03.790 7775-1067/rpi.rpicam E/VLC: [0000007f70a3f4b8] core input: VLC is unable to open the MRL 'file:////http%3A//70.122.174.124%3A691'. Check the log for details. 

Мне ясно, что проблема заключается в том, что VLC думает, что я пытаюсь получить доступ к файлу, который хранится на устройство, а не потоковое видео с http.

Я попытался выполнить поиск через переполнение стека и документацию VLC, но, похоже, не слишком много документации, и я не могу понять, как заставить VLC распознавать, что это поток HTTP.

Другие детали: Я проверил, что поток работает, наблюдая его с помощью VLC на моем Ubuntu Desktop и официальное приложение VLC для Android

, когда я начала свою деятельность, соответствующую коде выше, все, что я вижу черный экран

+0

Вы пробовали 'new Media (libvlc, Uri.parse (media))'? – CommonsWare

+0

Вы знаете, что я клянусь, что раньше я это пробовал, и это не сработало ... но я думаю, не потому, что это так. Начал с экрана компьютера слишком долго o.O. Хотите представить это как рекомендуемый ответ, чтобы я мог отметить его правильно? – William

ответ

0

Есть несколько конструкторов Media. Тот, который принимает String в качестве второго параметра, документируется как ожидающий, что этот параметр является локальным файловым путем.

(ИМХО, это была не большой API дизайн — использования File объектов для этого)

Там находится еще один Media конструктора, который принимает Uri в качестве параметра; что, скорее всего, будет работать с другими типами схем, например https.

Смежные вопросы