How To Stream RTMP live in Android - Truiton
Skip to content

How To Stream RTMP live in Android

Android RTMP Player

Streaming live video/audio in android is one of the very few interesting parts we have. Whenever we talk of streaming, the possibility of using RTMP(Real Time Messaging Protocol) cannot be ruled out. As RTMP is one of the most basic protocols available for streaming live video/audio feed. But unfortunately Android’s standard VideoView does not support the playback of RTMP streams. Therefore to natively play a live RTMP stream on Android, an external library is required which can provide us an Android RTMP player. As of now I have discovered two libraries which can serve this purpose.

First being the Android Vitamio library, and second being the LibVLC SDK for Android. In my opinion the later one is the better one. As this comes in a form of a plug-in solution from the open source organisation that built the worlds greatest video player ever, that right:- VLC. Therefore in this tutorial to build an example of Android RTMP player we will discuss how we can use the LibVLC SDK for Android. But before doing so lets, also have an overview of its counterpart, Vitamio library as well.

Android Vitamio Library

Vitamio is an open source project for Android and iOS built up on FFmpeg code. Vitamio provides us a clean and simple API with full and real hardware accelerated decoder and render-er. Vitamio is a very powerful library which supports a wide variety of video/audio formats like FLV, TS/TP, WMV, DivX, Xvid and many other standard formats. What makes it different is that it also supports the playback of embedded and external subtitles like .mkv and .srt. But Vitamio comes with a license, hence please go through this license page before using it in your project. In this Android RTMP example, we will not only discuss the live streaming of RTMP stream in Android, but will also discuss how we can stream m3u8 playlists(HLS), RTSP streams and MMS (Microsoft Media Stream). But through the usage of VLCs SDK for Android.

Android VLC SDK

VLC Media Player has been the most popular video file playback software available till date. The interesting part about it is that, it supports all major video/audio playback formats. Therefore when compared with other SDKs or libraries like Vitamio for RTMP streaming, it is considered to be far more superior by default. This gives us an obvious answer why we should use this LibVLC SDK for Android. Coincidentally, it is not very difficult to use this SDK in an Android app. Once done, you can play all the playback formats it supports, be it HLS, RTMP, RTSP, or even subtitles. Full SDK docs are available here. Therefore, without waiting lets integrate it in our app.

How to embed VLC Media Player in your Android App?

To use Android VLC Media Player SDK in your app, you may need to include the compiled code for vlc media player in your app. To do so, two ways are available:

Option 1: Manually compile SDK and use it through NDK as .so file:

Option 2: Use a Gradle dependency, compiled as an opensource project vlc-android-sdk by mrmaffen (May not be the latest version always).

So for this Android RTMP Streaming Example, I will be using this option. To do so, all you need to do is in your build.gradle (app) file, add a dependency as shown:

dependencies {
    compile "de.mrmaffen:vlc-android-sdk:2.0.6"
}

Streaming RTMP Stream Live in Android

Before heading directly to the implementation part, first lets understand RTMP a little. Real Time Messaging Protocol (RTMP) is a protocol owned by Adobe Systems. This protocol was developed to stream audio and video content to company’s proprietary flash player. But later on as it evolved, a part of it was released for public use. More of it can be read here. Mostly this type of protocol is used for IPTV and live VoD streaming, but it can be used in many other areas as well.

To play an RTMP stream in Android, a normal VideoView cannot be used, as it does not support the RTMP playback. But a WebView can be used to play the RTMP stream without any external library. This solves the problem but in my personal opinion web apps don’t give a nice look and feel to an app. Hence in this Android RTMP example we will be using an external SDK – VLC Media Player for streaming a live RTMP stream. After including it in the project, please add a SurfaceView in your layout file:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    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"
    tools:context=".MainActivity">

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

Further to run this Android RTMP player, please code your activity something like this:

package com.truiton.rtmpplayer;

import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Gravity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup.LayoutParams;
import android.widget.Toast;

import org.videolan.libvlc.IVLCVout;
import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.Media;
import org.videolan.libvlc.MediaPlayer;

import java.lang.ref.WeakReference;
import java.util.ArrayList;


public class MainActivity extends AppCompatActivity implements IVLCVout.Callback {
    public final static String TAG = "MainActivity";
    private String mFilePath;
    private SurfaceView mSurface;
    private SurfaceHolder holder;
    private LibVLC libvlc;
    private MediaPlayer mMediaPlayer = null;
    private int mVideoWidth;
    private int mVideoHeight;

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

        mFilePath = "rtmp://rrbalancer.broadcast.tneg.de:1935/pw/ruk/ruk";

        Log.d(TAG, "Playing: " + mFilePath);
        mSurface = (SurfaceView) findViewById(R.id.surface);
        holder = mSurface.getHolder();
    }

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


    /**
     * Used to set size for SurfaceView
     *
     * @param width
     * @param height
     */
    private void setSize(int width, int height) {
        mVideoWidth = width;
        mVideoHeight = height;
        if (mVideoWidth * mVideoHeight <= 1)
            return;

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

        int w = getWindow().getDecorView().getWidth();
        int h = getWindow().getDecorView().getHeight();
        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);

        holder.setFixedSize(mVideoWidth, mVideoHeight);
        LayoutParams lp = mSurface.getLayoutParams();
        lp.width = w;
        lp.height = h;
        mSurface.setLayoutParams(lp);
        mSurface.invalidate();
    }

    /**
     * Creates MediaPlayer and plays video
     *
     * @param media
     */
    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<String>();
            //options.add("--subsdec-encoding <encoding>");
            options.add("--aout=opensles");
            options.add("--audio-time-stretch"); // time stretching
            options.add("-vvv"); // verbosity
            libvlc = new LibVLC(this, options);
            holder.setKeepScreenOn(true);

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

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

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

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

    /**
     * Registering callbacks
     */
    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 onSurfacesCreated(IVLCVout vout) {

    }

    @Override
    public void onSurfacesDestroyed(IVLCVout vout) {

    }

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

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

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

        @Override
        public void onEvent(MediaPlayer.Event event) {
            MainActivity 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;
            }
        }
    }
}

Although the above code is self explanatory, but please dont forget to change the RTMP path to play your stream. At times to stream an RTMP stream in Android, you may have to pass the headers along with the path. Luckily you may have seen above that LibVLC supports that too. Hence all types of RTMP streams can be used with Android VLC SDK. The above example would look something like this:

Android RTMP Stream Live

But before moving on to other parts, please don’t forget to add configChanges flag in your AndroidManifest for this Activity, as shown:

        <activity
            android:name=".MainActivity"
            android:configChanges="orientation|screenSize"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

Full source code is also available here:

Full Source Code

Android RTSP Streaming

Real Time Streaming Protocol (RTSP) is used for streaming content from media servers. Like YouTube uses RTSP streams to distribute content. The easy part about RTSP streaming is that, it can be done through the standard VideoView of Android. To read more about it please refer to my VideoView Example.

But if you are implementing a solution by using the embedded VLC Media Player Lib, you might prefer using the same for RTSP streaming as well. As a matter of fact Android VLC SDK supports all video/audio formats, hence it also supports the playback of RTSP stream. Therefore If you are building a media playback app, you may use the same code shown in the section above to playback an RTSP stream. All you need to do is replace the URL.

mFilePath = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov";

Android m3u8 Streaming

How to play m3u8 video in Android? is one of the most common questions among the Android developers. The easiest way to do HTTP Live Streaming (HLS) in Android is through the usage of standard VideoView. But as you might have guessed, there are some limitations to it. Through standard Android VideoView you can stream m3u8 streams but only on the devices having Android 3.0 and above. This is because the HTTP/HTTPS live streaming and HTTP/HTTPS progressive streaming protocols were introduced in Android 3.0 and full support with HTTPS was given in 3.1.

If you wish to do HTTP Live Streaming (HLS) and support Android m3u8 streaming, for earlier versions of android. You should consider using the Android LibVLC, as this library adds the support for playback of m3u8 lists along with many other formats on android API 9 and above. To do so the process is same- as shown in the sections above, just replace the URL with m3u8, HTTP Live Streaming URL:

mFilePath = "http://93.184.221.133/00573D/236/236-0.m3u8";

Playing m3u8 stream on Android with VLC SDK would look something like this:

Android m3u8 Streaming

Android MMS Stream

Another uncommon format for streaming in Android is MMS. Since the Android LibVLC is a powerful library which supports very complex video playback formats, it also supports the playback of Microsoft Media Server (MMS) stream. Hence one should use this SDK to stream MMS as well. MMS is a network streaming protocol, mostly used for webcasts and live radio. Using embedded VLC media player library for the playback of an MMS stream in Android is not that different from using other protocols. All you have to do just replace the path variable to point to an MMS url:

mFilePath = "mms://beotelmedia.beotel.net/studiob";

Conclusion

As we discussed above, I would like to conclude by saying that LibVLC SDK is a very powerful multi-platform library, for iOS and Android both. By using Vitamio library one can stream limited types of video formats and protocols like RTMP, RTSP, HTTP Live, and HTTP progressive streaming protocol. But by using the Android VLC SDK, you can stream all the major video/audio formats available till date. Another great playback feature that comes along with LibVLC is that it supports the playback of subtitles and multiple audio tracks as well. Hope this helped. Connect with us through our Facebook, Google+ and Twitter profiles for more updates.

30 thoughts on “How To Stream RTMP live in Android”

  1. Hi Guys and Admin.

    When i include vitamio module on Android Studio. When i build. logcat show: ffmpeg.so not found. How can i fix ? I had research 3 days ago. But i can not fix.

    Thanks

      1. That’s a problem with android emulator,due to Vitamio use ARMv6 architecture….anyway you can try with your android phone and everything will be right

  2. I have a error “E/Vitamio[Player]﹕ Native libs libffmpeg.so not exists! ” when use it in Android Studio. Please help me. Thanks!

  3. hey , first of all , thanks for the tutorial is really heplfull. i just have a litle problem. i can not play rtmp streams with vitamio. i just can play rtsp and other formats, but not the rtmp url. i just have this error on the logcat : E/Vitamio[Player]: Native libs libffmpeg.so not exists!.

    I am very grateful if someone can assist me a little about what’s going on that error.

  4. Hi! Nice tutorial.
    i am using the vitamio for streaming audio only
    how can i edit the xml file so it doesnt show a blank video view while the audio is streaming

  5. Hi, thanks for this amazing tutorial. i tried this and it works just fine.
    Now i want to ask How can i run vitamio in background like from a service. Actually i am playing an audio with vitamio player. it works good. But as i close that activity or whole app its stop playing. which is good for a video, but i want to play my audio in background. Please help me. thanks in advance 🙂

  6. Hi Admin and Guyz,
    I am using Vitamio streaming library to play rtsp stream in android device. It’s playing amazingly. But I am getting initial latency 1-2 sec (Which is great.) and after some time (5-10 mins), latency starts increasing up to 10-15 sec as buffer gets full.
    Any idea how we flush/clear buffer in some particular time interval.
    Any help would be greatly appreciated.
    Thanks.

  7. First, thank you by tutorial. I realized when I press the stop button in media controller and I wait some seconds, the phone enter in background mode and starts by itself the music again. How could I fix it?

  8. thanks, but could you help me with how open on a new layout,
    i want to call from main activity but i want to play video on another layout.
    thanks

  9. I have used this vitamio library… but there is one issue when we attach the media controller video-view moves little up and the UI gets distorted. Any Help

  10. Error occurred while importing module in android studio. Saying ‘cannot find file /../../../settings.jar’.
    I have unzipped it but can’t move further as the jar file is not found.

  11. Really thanks for this tutorial. its working fine but its not working when i using nougat. i got an error unfortunately “StreamingApp has stopped”. Can anyone help me.

  12. Hi Guys,

    I have updated the article and also have posted a link for full source code. Now you can do RTMP streaming through the official VLC Media Player SDK for Android.

    -Mohit Gupt

  13. RTMP links with token are not working

    09-18 19:11:05.971 2991-3926/com.livetv.android.apps.uktvnow E/VLC: [964b0228/f56] avio access: Failed to open rtmp://play.uktvnow.net/live?wmsAuthSign=c2VydmVyX3RpbWU9OS8xOC8yMDE3IDI6MTE6MDIgUE0maGFzaF92YWx1ZT1NU2V0RmVqbEZVY2lmS1dmTENlRmF3PT0mdmFsaWRtaW51dGVzPTIw/usae.stream: Operation not permitted
    09-18 19:11:05.971 2991-3926/com.livetv.android.apps.uktvnow D/VLC: [964b0228/f56] core access: no access modules matched
    09-18 19:11:05.971 2991-3926/com.livetv.android.apps.uktvnow E/VLC: [964a80e8/f56] core input source: cannot access rtmp://play.uktvnow.net/live?wmsAuthSign=c2VydmVyX3RpbWU9OS8xOC8yMDE3IDI6MTE6MDIgUE0maGFzaF92YWx1ZT1NU2V0RmVqbEZVY2lmS1dmTENlRmF3PT0mdmFsaWRtaW51dGVzPTIw/usae.stream
    09-18 19:11:05.971 2991-3926/com.livetv.android.apps.uktvnow E/VLC: [90fad6c8/f56] core input: Your input can’t be opened
    09-18 19:11:05.971 2991-3926/com.livetv.android.apps.uktvnow E/VLC: [90fad6c8/f56] core input: VLC is unable to open the MRL ‘rtmp://play.uktvnow.net/live?wmsAuthSign=c2VydmVyX3RpbWU9OS8xOC8yMDE3IDI6MTE6MDIgUE0maGFzaF92YWx1ZT1NU2V0RmVqbEZVY2lmS1dmTENlRmF3PT0mdmFsaWRtaW51dGVzPTIw/usae.

    Any Help?

  14. Hello!
    Congratulation for the tutorial!

    I have used the vlc library but I have a problem!
    I have used it to display GoPro Hero4 live streaming in Android (from udp url). Ok it display the live stream, but it see very bad (there are many squares and strange things….)..
    If I open the same udp url stream from windows vlc, it see very well.

    Why?

    Thank you very much!
    Best Regards!!

  15. In case you wanna play RTSP streamings across your network and not just VOD:

    In method “createPlayer” you MUST add:
    options.add(“–rtsp-tcp”);

  16. Hello, I am satisfied with this tutorial but i wish to know how you can use webview to play rtmp without any external library. I need your help.
    thank you in advance.

  17. I would like to thank you for this precious work.
    Your post, Sir, literally saved my life….
    I do really appreciated!!!
    keep it up
    And thank you again 🙂

  18. I could not see seekbar on rtsp or hls link, i want this because i am playing wowza steam which provides live stream with recorded video.

  19. Thanks for sharing an awesome tutorial,
    But I am facing an issue

    avio access: Failed to open rtmp://194.79.52.79/ockoi/ockoHQ1: Connection refused
    E/VLC: [00000073834e8c88/714] core input source: cannot access rtmp://194.79.52.79/ockoi/ockoHQ1
    E/VLC: [00000073835e8e08/714] core input: Your input can’t be opened
    E/VLC: [00000073835e8e08/714] core input: VLC is unable to open the MRL ‘rtmp://194.79.52.79/ockoi/ockoHQ1’. Check the log for details.

  20. Great tutorial ! However, just wanna know why does it take so long to return back to MainActivity? Is there a quicker way to return back to previous Activity. Tried releasePlayer() but it still take at least 30 seconds before returning.

Leave a Reply

Your email address will not be published. Required fields are marked *