2

I am trying to stream live webcam video from Ubuntu 12.04 PC to android device with KitKat. So far I've written ffserver config file to receive ffm feed and broadcast it through a rtsp protocol. I am able to watch the stream on the other computer in the same LAN with ffplay.

How to watch the stream on the android device? The following code works well when the webcam image is streamed with vlc but it doesn't with ffmpeg:

public class MainActivity extends Activity implements MediaPlayer.OnPreparedListener,
        SurfaceHolder.Callback {

    final static String RTSP_URL = "rtsp://192.168.1.54:4424/test.sdp";

    private MediaPlayer _mediaPlayer;
    private SurfaceHolder _surfaceHolder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Set up a full-screen black window.
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        Window window = getWindow();
        window.setFlags(
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        window.setBackgroundDrawableResource(android.R.color.black);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        setContentView(R.layout.activity_main);

        // Configure the view that renders live video.
        SurfaceView videoView =
                (SurfaceView) findViewById(R.id.videoView); //where R.id.videoView is a simple SurfaceView element in the layout xml file
        _surfaceHolder = videoView.getHolder();
        _surfaceHolder.addCallback(this);
        _surfaceHolder.setFixedSize(320, 240);
    }
    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        _mediaPlayer = new MediaPlayer();
        _mediaPlayer.setDisplay(_surfaceHolder);
        Context context = getApplicationContext();
        Uri source = Uri.parse(RTSP_URL);
        try {
            // Specify the IP camera's URL and auth headers.
            _mediaPlayer.setDataSource(context, source);

            // Begin the process of setting up a video stream.
            _mediaPlayer.setOnPreparedListener(this);
            _mediaPlayer.prepareAsync();
        }
        catch (Exception e) {}
    }
    @Override
    public void onPrepared(MediaPlayer mediaPlayer) {
        _mediaPlayer.start();
    }
}

My ffserver.config file:

HTTPPort 8090
RTSPBindAddress 0.0.0.0
RTSPPort 4424
MaxBandwidth 10000
CustomLog -

<Feed feed1.ffm>
        File /tmp/feed1.ffm
        FileMaxSize 20M
        ACL allow 127.0.0.1
</Feed>
<Stream test1.sdp>
    Feed feed1.ffm
    Format rtp  
    VideoCodec libx264
    VideoSize 640x480
    AVOptionVideo flags +global_header
    AVOptionVideo me_range 16
    AVOptionVideo qdiff 4
    AVOptionVideo qmin 10
    AVOptionVideo qmax 51
    Noaudio
    ACL allow localhost
        ACL allow 192.168.0.0 192.168.255.255
</Stream>

I am starting the stream with this command: ffmpeg -f v4l2 -i /dev/video0 -c:v libx264 -b:v 600k http://localhost:8090/feed1.ffm

grzebyk
  • 1,024
  • 1
  • 15
  • 26
  • Maybe use Wireshark to check what is happening at the RTSP level - is the connection opened, is the track found? If the track is not found the the issue is most likely at the ffserver, otherwise if data is pushed there could be issues with the format that Android can't handle. – Rudolfs Bundulis Oct 20 '14 at 08:43
  • I checked formats supported by android [here](http://developer.android.com/guide/appendix/media-formats.html) and I am using supported one. I am also sure that connection is opened and registered by ffserver. Console output: `Mon Oct 20 17:04:53 2014 192.168.1.55 - - [DESCRIBE] "rtsp://192.168.1.54:4424/test.sdp RTSP/1.0" 200 72` – grzebyk Oct 20 '14 at 15:05
  • And logcat in Android Studio shows the following error MediaPlayer﹕ Error (1,-2147483648), which is unknown (described [here](http://stackoverflow.com/questions/11540076/android-mediaplayer-error-1-2147483648) ) – grzebyk Oct 20 '14 at 15:50
  • 1
    The post you mentioned contained this `07-18 13:47:14.245: W/QCvdec(68): Parsing Error unsupported profile or level` - do you have that too? libx264 could be using unsupported compression parameters while vlc could be using supported ones. – Rudolfs Bundulis Oct 20 '14 at 21:25
  • No I don't. I only have `D/MediaPlayer﹕ Couldn't open file on client side, trying server side W/MediaPlayer﹕ info/warning (701, 0) E/MediaPlayer﹕ error (1, -2147483648)` – grzebyk Oct 20 '14 at 22:35
  • Well, just for a test you can try adding `-profile baseline` or `-vprofile baseline` to the ffmpeg command line (seems that `profile` option is broken in some versions) to see if that helps. – Rudolfs Bundulis Oct 21 '14 at 07:26
  • I added `-profile:v main` but ffmpeg spit out error `x264 [error]: main profile doesn't support 4:2:2`. I dig into [ffmpeg](http://ffmpeg.org/ffmpeg.html) and [ffserver](http://ffmpeg.org/ffserver.html) documentation and I found that I have to add `-pix_fmt yuv420p` to console syntax and `PixelFormat yuv420p` to ffserver config file. Now it's all working :) Thank you Rudolfs for advices where to look for a mistake. You can post the solution as an answer and I'll accept it. – grzebyk Oct 21 '14 at 10:06
  • thanks for the feedback, I added the answer, btw weird that in the other post Android actually complained about the profile but you got no errors, RTP and AVC can be confusing. – Rudolfs Bundulis Oct 21 '14 at 10:13

1 Answers1

0

This error could be most likely caused by different encoding parameters for VLC and FFmpeg - VLC could use encoding parameters that Android is able support, but FFmpeg could use unsupported ones (most likely AVC profile and level). Try to force baseline or main profile and YUV 4:2:0 pixel format through the FFmpeg command line options and ffserver.config.

Rudolfs Bundulis
  • 11,636
  • 6
  • 33
  • 71