Search code examples
androidrtmpexoplayer

Recording of RTMP stream


I have a class, which watching rtmp stream with help of ExoPLayer:

    player = ExoPlayerFactory.newSimpleInstance(context)
    val rtmpDataSourceFactory = RtmpDataSourceFactory()
    val videoSource = ProgressiveMediaSource.Factory(rtmpDataSourceFactory)
            .createMediaSource(Uri.parse(streamURL))

    player.prepare(videoSource)
    player.setVideoTextureView(playerView)
    player.playWhenReady = true

playerView is TextureView, picked instead of SurfaceView, because i also need to take screenshots from stream.

As far as i know, ExoPlayer does not have methods for stream recording, only downloading, so problem is - how can i record rtmp stream? I searched a lot of libraries, and Stack questions but still cant find clean, normal solution.

At the moment i am trying to record stream by basic MediaRecorder, with help Android developer documentation, but i still dont understand, how MediaRecorder acquire stream data or at least surface.

val path = "${Environment.getExternalStorageDirectory()}${File.separator}${Environment.DIRECTORY_DCIM}${File.separator}${"FILE_NAME"}"

        recorder = MediaRecorder().apply {
            setVideoSource(MediaRecorder.VideoSource.SURFACE)
            setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
            setOutputFile(path)

            start()
        }

Solution

  • I found the solution by using FFMpeg library. If someone needs it - add this Gradle dependency: implementation 'com.writingminds:FFmpegAndroid:0.3.2

    And here is the code:

            // Build path for recorded video
            val title = "/" + System.currentTimeMillis().toString() + ".mp4"
            val targetFile = File(getExternalStoragePublicDirectory(DIRECTORY_DCIM).toString() + title)
    
            // FFMpeg command for stream recording
            val command = arrayOf("-i", streamURL, "-acodec", "copy", "-vcodec", "copy", targetFile.toString())
    
            try {
                // Load the binary
                ffmpeg.loadBinary(object : LoadBinaryResponseHandler() {})
            } catch (e: FFmpegNotSupportedException) {
                e.printStackTrace()
            }
    
            try {
                // Execute command
                ffmpeg.execute(command, object : ExecuteBinaryResponseHandler() {})
            } catch (e: FFmpegCommandAlreadyRunningException) {
                e.printStackTrace()
            }