bytedeco / javacv

Java interface to OpenCV, FFmpeg, and more
Other
7.5k stars 1.57k forks source link

Problem with webm streaming #342

Open Arronaks opened 8 years ago

Arronaks commented 8 years ago

Hello all! Can you help me with this issue? I modify RecordActivity example: 1) Change ffmpeg_link to "http://192.168.0.143:8890/main.ffm"; 2) Change final int RECORD_LENGTH = 0; 3) Add setting for recorder:

    recorder = new FFmpegFrameRecorder(ffmpeg_link, imageWidth, imageHeight, 1);
    recorder.setFormat("ffm");
    recorder.setFrameRate(frameRate);
    recorder.setVideoBitrate(400);
    recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
    recorder.setVideoCodec(avcodec.AV_CODEC_ID_VP9);

    recorder.setSampleRate(sampleAudioRateInHz);
    recorder.setAudioBitrate(64);
    recorder.setAudioChannels(2);
    recorder.setAudioCodec(avcodec.AV_CODEC_ID_VORBIS);

4) Run ffserver on arch linux with this config file:


HttpPort 8890                      # Port to bind the server to
HttpBindAddress 0.0.0.0
MaxHTTPConnections 2000 
MaxClients 1000
MaxBandwidth 40000             # Maximum bandwidth per client
NoDefaults

<Feed main.ffm>               # This is the input feed where FFmpeg will send
   File /tmp/main.ffm            # video stream.
   FileMaxSize 100M              # Maximum file size for buffering video
   # Launch ffmpeg -f video4linux2 -s 320x240 -thread_queue_size 100 -i /dev/vid$
   #  ACL allow 192.168.0.0
   # Allowed IPs
</Feed>

<Stream live.webm>                      # Output stream URL definition
   Feed main.ffm              # Feed from which to receive video
   Format webm
   # Audio settings
   AudioCodec vorbis
   AudioChannels 2
   AudioBitRate 64             # Audio bitrate
   AudioSampleRate 44100
   #AudioCodec libmp3lame
   # Video settings
   VideoCodec libvpx
   VideoBufferSize 40000
   VideoSize 320x240           # Video resolution
   VideoFrameRate 30           # Video FPS
   AVOptionVideo flags +global_header
   AVOptionVideo cpu-used 8
   AVOptionVideo me_range 16
   AVOptionVideo qdiff 4
   AVOptionVideo qmin 10
   AVOptionVideo qmax 51
   AVOptionVideo quality good
   AVOptionAudio flags +global_header
   PreRoll 1
   # StartSendOnKey
   VideoBitRate 400            # Video bitrate
   PixelFormat yuv420p

</Stream>

<Stream status.html>                    # Server status URL
   Format status
   # Only allow local people to get the status
   ACL allow localhost
   ACL allow 0.0.0.0 0.0.255.255
</Stream>

When i start streaming i found this in server log

Mon Feb 29 12:24:15 2016 [webm @ 0x55680d784f10]Codec for stream 0 does not use global headers but container format requires global headers Mon Feb 29 12:24:15 2016 [webm @ 0x55680d784f10]Codec for stream 1 does not use global headers but container format requires global headers Mon Feb 29 12:24:15 2016 [webm @ 0x55680d784f10]Extradata corrupt. Mon Feb 29 12:24:15 2016 Error writing output header for stream 'live.webm': Operation not permitted

Server version:

ffmpeg version 2.8.5 Copyright (c) 2000-2016 the FFmpeg developers built with gcc 5.3.0 (GCC)

Jar version in Android Studio:

ffmpeg-2.8.1-1.1

If i change recorder.setFormat("ffm"); to recorder.setFormat("webm"); I don't see stream on server at all. Where I made ​​a mistake? Thanks in advance and sorry for my english.

saudet commented 8 years ago

They say here that the FFM format may not be compatible across versions so you might want to try FFM2 instead: https://ffmpeg.org/ffserver.html#FFM_002c-FFM2-formats

Arronaks commented 8 years ago

Thank you for help, Saudet. I change server configuration:

...
<Feed main.ffm2>               # This is the input feed where FFmpeg will send
   File /tmp/main.ffm2            # video stream.
   FileMaxSize 100M              # Maximum file size for buffering video
   # Launch ffmpeg -f video4linux2 -s 320x240 -thread_queue_size 100 -i /dev/vid$
   #  ACL allow 192.168.0.0
   # Allowed IPs
</Feed>

<Stream live.webm>                      # Output stream URL definition
   Feed main.ffm2 
...

And ffmpeg_link string in java code. In this case i get the same error from ffserver. If i additionally change setFormat("ffm") to setFormat("ffm2") i get error:

org.bytedeco.javacv.FrameRecorder$Exception: av_guess_format() error: Could not guess output format for "http://192.168.0.143:8890/main.ffm2" and ffm2 format.

saudet commented 8 years ago

Looks like we can't choose FFM2, seems to be the only available version...

Anyway, do you get the same issue when using FFmpegFrameRecorder on Linux?

Arronaks commented 8 years ago

I wrote simple example, but on Windows 7...

        ...
    public static void main(String[] args)
    {       
        FFmpegFrameRecorder recorder;
        String ffmpeg_link = "http://192.168.0.143:8890/main.ffm2";
        int sampleAudioRateInHz = 44100;
        int imageWidth = 320;
        int imageHeight = 240;
        int frameRate = 30;

        recorder = new FFmpegFrameRecorder(ffmpeg_link, imageWidth, imageHeight, 1);
        recorder.setFormat("ffm2");
        recorder.setFrameRate(frameRate);
        recorder.setVideoBitrate(400);
        recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_VP9);
        recorder.setSampleRate(sampleAudioRateInHz);
        recorder.setAudioBitrate(64);
        recorder.setAudioChannels(2);
        recorder.setAudioCodec(avcodec.AV_CODEC_ID_VORBIS);

        try {
            recorder.start();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
           ...

I got same error as is on Android:

org.bytedeco.javacv.FrameRecorder$Exception: av_guess_format() error: Could not guess output format for "http://192.168.0.143:8890/main.ffm2" and ffm2 format. at org.bytedeco.javacv.FFmpegFrameRecorder.startUnsafe(FFmpegFrameRecorder.java:315) at org.bytedeco.javacv.FFmpegFrameRecorder.start(FFmpegFrameRecorder.java:288) at main_class.main(main_class.java:45)

saudet commented 8 years ago

ffm2 doesn't seem to be defined, so what about ffm?

Arronaks commented 8 years ago

If i change ffm to ffm2 on ffserver config file, everything remains as in my first message:

Mon Feb 29 12:24:15 2016 [webm @ 0x55680d784f10]Codec for stream 0 does not use global headers but container format requires global headers Mon Feb 29 12:24:15 2016 [webm @ 0x55680d784f10]Codec for stream 1 does not use global headers but container format requires global headers Mon Feb 29 12:24:15 2016 [webm @ 0x55680d784f10]Extradata corrupt. Mon Feb 29 12:24:15 2016 Error writing output header for stream 'live.webm': Operation not permitted

Now I downloaded ffmpeg-2.8.1 sources and trying to build it on server machine. Versions will be the same and ffm2 will not be required.

Arronaks commented 8 years ago

I install same version on server machine (2.8.1) and nothing changes.

saudet commented 8 years ago

Hum, maybe the global header flag here isn't getting set for some reason: https://github.com/bytedeco/javacv/blob/master/src/main/java/org/bytedeco/javacv/FFmpegFrameRecorder.java#L428

Arronaks commented 8 years ago

You're right, in 309 str if ((oformat = av_guess_format(format_name, filename, null)) == null) { we get ffm format and oformat.flags() returns 0x4000. But AVFMT_GLOBALHEADER = 0x40. Because of this we cant determine global headers flag in 430 string. What can I do with this?

saudet commented 8 years ago

So, if we force CODEC_FLAG_GLOBAL_HEADER does it work? If so, I guess we'll need to ask the authors of FFmpeg under which conditons we should set this flag... Or we could start by setting it by default at least for ffm?

Arronaks commented 8 years ago

If we force CODEC_FLAG_GLOBAL_HEADER flag (I just created a duplicate class and commented out conditions for this flag) ffserver writes this:

Tue Mar 1 15:59:33 2016 [webm @ 0x2923830]Writing block at offset 16, size 698, pts 6153, dts 6153, duration 1, keyframe 1 Tue Mar 1 15:59:33 2016 [webm @ 0x2923830]Writing block at offset 721, size 746, pts 6177, dts 6177, duration 1, keyframe 1 Tue Mar 1 15:59:33 2016 [webm @ 0x2923830]Writing block at offset 1474, size 788, pts 6200, dts 6200, duration 1, keyframe 1 ,,.

I think the problem with global headers solved. Thank you for help! But now, it seems like stream incorrectly configured....

Arronaks commented 8 years ago

I made mistake with server output. ffserver also often writes this:

Tue Mar 1 16:44:49 2016 [webm @ 0x29258d0]Starting new cluster at offset 5494 bytes, pts 1200dts 1200

like this:

Tue Mar 1 16:44:22 2016 [webm @ 0x29258d0]Writing block at offset 797, size 790, pts 557, dts 557, duration 1, keyframe 1 Tue Mar 1 16:44:22 2016 [webm @ 0x29258d0]Writing block at offset 1594, size 29, pts 567, dts 567, duration 33, keyframe 1 Tue Mar 1 16:44:22 2016 [webm @ 0x29258d0]Writing block at offset 1629, size 756, pts 580, dts 580, duration 1, keyframe 1 Tue Mar 1 16:44:22 2016 [webm @ 0x29258d0]Writing block at offset 2392, size 30, pts 600, dts 600, duration 33, keyframe 1 Tue Mar 1 16:44:22 2016 [webm @ 0x29258d0]Writing block at offset 2428, size 740, pts 604, dts 604, duration 1, keyframe 1 Tue Mar 1 16:44:23 2016 [webm @ 0x29258d0]Writing block at offset 3175, size 674, pts 627, dts 627, duration 1, keyframe 1 Tue Mar 1 16:44:23 2016 [webm @ 0x29258d0]Writing block at offset 3856, size 686, pts 650, dts 650, duration 1, keyframe 1 Tue Mar 1 16:44:23 2016 [webm @ 0x29258d0]Writing block at offset 4549, size 30, pts 667, dts 667, duration 33, keyframe 1 Tue Mar 1 16:44:23 2016 [webm @ 0x29258d0]Writing block at offset 4585, size 712, pts 673, dts 673, duration 1, keyframe 1 Tue Mar 1 16:44:23 2016 [webm @ 0x29258d0]Writing block at offset 5304, size 714, pts 697, dts 697, duration 1, keyframe 1 > Tue Mar 1 16:44:23 2016 [webm @ 0x29258d0]Starting new cluster at offset 6025 bytes, pts 733dts 733 Tue Mar 1 16:44:23 2016 [webm @ 0x29258d0]Writing block at offset 16, size 723, pts 720, dts 720, duration 1, keyframe 1 Tue Mar 1 16:44:23 2016 [webm @ 0x29258d0]Writing block at offset 746, size 22, pts 733, dts 733, duration 33, keyframe 1 Tue Mar 1 16:44:29 2016 [webm @ 0x29258d0]Writing block at offset 774, size 722, pts 743, dts 743, duration 1, keyframe 1 Tue Mar 1 16:44:29 2016 [webm @ 0x29258d0]Writing block at offset 1503, size 762, pts 766, dts 766, duration 1, keyframe 1 Tue Mar 1 16:44:29 2016 [webm @ 0x29258d0]Writing block at offset 2272, size 754, pts 789, dts 789, duration 1, keyframe 1 Tue Mar 1 16:44:29 2016 [webm @ 0x29258d0]Writing block at offset 3033, size 478, pts 800, dts 800, duration 33, keyframe 1 Tue Mar 1 16:44:29 2016 [webm @ 0x29258d0]Writing block at offset 3518, size 774, pts 813, dts 813, duration 1, keyframe 1 Tue Mar 1 16:44:29 2016 [webm @ 0x29258d0]Writing block at offset 4299, size 36, pts 833, dts 833, duration 33, keyframe 1 Tue Mar 1 16:44:29 2016 [webm @ 0x29258d0]Writing block at offset 4341, size 735, pts 836, dts 836, duration 1, keyframe 1 Tue Mar 1 16:44:37 2016 [webm @ 0x29258d0]Writing block at offset 5083, size 731, pts 859, dts 859, duration 1, keyframe 1 > Tue Mar 1 16:44:37 2016 [webm @ 0x29258d0]Starting new cluster at offset 5821 bytes, pts 900dts 900 Tue Mar 1 16:44:37 2016 [webm @ 0x29258d0]Writing block at offset 16, size 794, pts 882, dts 882, duration 1, keyframe 1 Tue Mar 1 16:44:37 2016 [webm @ 0x29258d0]Writing block at offset 817, size 31, pts 900, dts 900, duration 33, keyframe 1 Tue Mar 1 16:44:37 2016 [webm @ 0x29258d0]Writing block at offset 854, size 907, pts 906, dts 906, duration 1, keyframe 1 Tue Mar 1 16:44:37 2016 [webm @ 0x29258d0]Writing block at offset 1768, size 818, pts 929, dts 929, duration 1, keyframe 1 Tue Mar 1 16:44:37 2016 [webm @ 0x29258d0]Writing block at offset 2593, size 919, pts 952, dts 952, duration 1, keyframe 1 Tue Mar 1 16:44:37 2016 [webm @ 0x29258d0]Writing block at offset 3519, size 38, pts 967, dts 967, duration 33, keyframe 1 Tue Mar 1 16:44:40 2016 [webm @ 0x29258d0]Writing block at offset 3563, size 809, pts 975, dts 975, duration 1, keyframe 1 Tue Mar 1 16:44:40 2016 [webm @ 0x29258d0]Writing block at offset 4379, size 824, pts 998, dts 998, duration 1, keyframe 1 > Tue Mar 1 16:44:40 2016 [webm @ 0x29258d0]Starting new cluster at offset 5210 bytes, pts 1033dts 1033 Tue Mar 1 16:44:40 2016 [webm @ 0x29258d0]Writing block at offset 16, size 769, pts 1022, dts 1022, duration 1, keyframe 1 Tue Mar 1 16:44:40 2016 [webm @ 0x29258d0]Writing block at offset 792, size 34, pts 1033, dts 1033, duration 33, keyframe 1 Tue Mar 1 16:44:40 2016 [webm @ 0x29258d0]Writing block at offset 832, size 761, pts 1045, dts 1045, duration 1, keyframe 1 Tue Mar 1 16:44:49 2016 [webm @ 0x29258d0]Writing block at offset 1600, size 805, pts 1068, dts 1068, duration 1, keyframe 1 Tue Mar 1 16:44:49 2016 [webm @ 0x29258d0]Writing block at offset 2412, size 793, pts 1091, dts 1091, duration 1, keyframe 1 Tue Mar 1 16:44:49 2016 [webm @ 0x29258d0]Writing block at offset 3212, size 32, pts 1100, dts 1100, duration 33, keyframe 1 Tue Mar 1 16:44:49 2016 [webm @ 0x29258d0]Writing block at offset 3250, size 755, pts 1115, dts 1115, duration 1, keyframe 1 Tue Mar 1 16:44:49 2016 [webm @ 0x29258d0]Writing block at offset 4012, size 30, pts 1133, dts 1133, duration 33, keyframe 1 Tue Mar 1 16:44:49 2016 [webm @ 0x29258d0]Writing block at offset 4048, size 734, pts 1138, dts 1138, duration 1, keyframe 1 Tue Mar 1 16:44:49 2016 [webm @ 0x29258d0]Writing block at offset 4789, size 698, pts 1161, dts 1161, duration 1, keyframe 1 Tue Mar 1 16:44:49 2016 [webm @ 0x29258d0]Starting new cluster at offset 5494 bytes, pts 1200dts 1200

saudet commented 8 years ago

I don't have a lot experience with that myself, so if you figure out how to modify FFmpegFrameRecorder to make this better, please let me know!