2016-12-20 1 views
0

Je suis en train de créer un flux en direct à partir d'une caméra attachée à un pi de framboise dans une application Android.VLC dans l'application Android à la recherche de fichier au lieu de flux http

Voici le code de l'activité:

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(); 
} 

} 

Et le 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> 

Cependant, quand je lance l'application que je reçois les erreurs suivantes dans les journaux:

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. 

Il est clair pour moi que le problème est que VLC pense que j'essaie d'accéder à un fichier qui est stocké sur l'appareil, plutôt que de diffuser la vidéo à partir de http.

J'ai essayé de rechercher par débordement de pile et la documentation VLC, mais il ne semble pas y avoir trop de documentation et je n'arrive pas à comprendre comment VLC reconnaît qu'il s'agit d'un flux http.

Autres détails: J'ai testé que le flux travaille en regardant via VLC sur mon Ubuntu Desktop et l'application officielle VLC Android

quand je commence l'activité correspondant au code ci-dessus, tout ce que je vois est un écran noir

+0

Avez-vous essayé 'new media (libvlc, Uri.parse (media))'? – CommonsWare

+0

Vous savez, je jure que j'avais déjà essayé ça et ça n'a pas marché ... mais je suppose que non parce que ça l'a fait. Été à partir d'un écran d'ordinateur trop longtemps o.O. Voulez-vous soumettre cela comme une suggestion de réponse afin que je puisse le corriger? – William

Répondre

0

Il existe quelques constructeurs Media. Celui qui prend un String en tant que deuxième paramètre est documenté comme s'attendant à ce que ce paramètre soit un chemin de fichier local.

(à mon humble avis, ce n'était pas un objet grand design API — utilisation File pour cela)

Il y a un autre constructeur Media qui prend un Uri comme paramètre; cela fonctionnera probablement avec d'autres types de schémas, comme https.