Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

H.264/MP2T over HTTP #90

Closed
juanpef opened this issue Oct 24, 2014 · 34 comments
Closed

H.264/MP2T over HTTP #90

juanpef opened this issue Oct 24, 2014 · 34 comments

Comments

@juanpef
Copy link

juanpef commented Oct 24, 2014

I have the next code:

    Uri uri = Uri.parse("http://192.166.103.140:8000/udp/239.192.0.49:2121");
    SampleSource sampleSource = new FrameworkSampleSource(mContext, uri, /* headers */ null , RENDERER_COUNT);
    MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource,
                MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 0, mainHandler,
                null, 50); 
    MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);
        ExoPlayer exoPlayer = ExoPlayer.Factory.newInstance(RENDERER_COUNT);
        exoPlayer.prepare(videoRenderer, audioRenderer);
        exoPlayer.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface);
        exoPlayer.setPlayWhenReady(true);

It works with a closed file like http://html5demos.com/assets/dizzy.mp4 but it does not work with a live streaming. What is the problem???

@andudo
Copy link
Contributor

andudo commented Oct 24, 2014

@juanpef
Copy link
Author

juanpef commented Oct 24, 2014

But I don't use HLS. I use h264 over HTTP. It would be the same use that the example? In that case, where can I fix the url? Thanks for your answer

@ojw28
Copy link
Contributor

ojw28 commented Oct 26, 2014

You're probably using a container format that isn't supported? See the "video" section of "core media formats" here: http://developer.android.com/guide/appendix/media-formats.html

@juanpef
Copy link
Author

juanpef commented Oct 27, 2014

No, because I play thne content with a simple VideoView without any problem.

@juanpef
Copy link
Author

juanpef commented Oct 27, 2014

I have played my content with a VideoView until now without problem. But now, with Exoplayer, I can't. We don’t use HLS, we stream the video as a H.264/MP2T over HTTP without any segmentation and I want to play it using Exoplayer. Is possible that this have not been implented yet?

Thanks

@juanpef
Copy link
Author

juanpef commented Oct 27, 2014

Tha url that we use is like http://server-ip:4022/rtp/239.0.0.77:8208

@andudo
Copy link
Contributor

andudo commented Oct 27, 2014

@juanpef if you just want to play a single standalone MPEG2TS file, then this is not supported. What you can do to work around:

  • Create a simple HLS playlist with just one file and use it as an HLS source.
  • Create your own TsChunkSource similar to HlsChunkSource (but much simpler), to just play a single file.

IMHO, MPEG2TS is probably not the right container format to use for stand alone video files.

@juanpef
Copy link
Author

juanpef commented Oct 27, 2014

@andudo Thanks four your answer.

I am using this code:

LoadControl loadControl = new DefaultLoadControl(new BufferPool(BUFFER_SEGMENT_SIZE));
String userAgent = getUserAgent(mContext);
Log.d(TAG, userAgent);
HlsMasterPlaylist manifest = newSimpleMasterPlaylist("http://www.nasa.gov/multimedia/nasatv/NTV-Public-IPS.m3u8");
DataSource dataSource = new HttpDataSource(userAgent, null, null);
HlsChunkSource chunkSource = new HlsChunkSource(dataSource, manifest);
HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl,
VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true, 2);
MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource,
MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 100, mainHandler, null, 50);
MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);
ExoPlayer exoPlayer = ExoPlayer.Factory.newInstance(RENDERER_COUNT);
exoPlayer.prepare(videoRenderer,audioRenderer);
// Pass the surface to the video renderer.
exoPlayer.sendMessage(videoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface);
exoPlayer.setPlayWhenReady(true);

With this other method:

private HlsMasterPlaylist newSimpleMasterPlaylist(String mediaPlaylistUrl) {
return new HlsMasterPlaylist(Uri.parse(""),
Collections.singletonList(new Variant(mediaPlaylistUrl, 0)));
}

And it does not work.

@andudo
Copy link
Contributor

andudo commented Oct 27, 2014

@juanpef newSimpleMasterPlaylist() is for the case where you only have a single media playlist URL and want to create a dummy master with it to reuse the same processing logic.
in your case you have a master playlist URL, you need to download it using ManifestFetcher, then parse using HlsMasterPlaylistParser and then feed the output to HlsChunkSource. look up the example link i gave to you earlier, it has all of it.

@juanpef
Copy link
Author

juanpef commented Oct 28, 2014

@andudo, thanks for your answer. And in my case in which I just want to play one URL? Would it not be more easy without any playlist?

@andudo
Copy link
Contributor

andudo commented Oct 28, 2014

@juanpef in your case with a single MPEG2TS file you can create a single media playlist and use the code you wrote above. without any playlist you'd also need to implement a ChunkSource for it, which shouldn't be hard.

@rogerjstringer
Copy link

Lack of support for "video/mp2t" is a very significant omission for ExoPlayer. This means MPEG-TS is not supported.

@juanpef
Copy link
Author

juanpef commented Oct 31, 2014

Could I use TsChunk.java for my purpose? In that case how can use it?

Thanks

@Schizo
Copy link

Schizo commented Apr 2, 2015

This should be an out of the box feature.

@ojw28
Copy link
Contributor

ojw28 commented Apr 2, 2015

  • We're working on a new extractor model that should make this easier to support (ETA 1-2 weeks).
  • Is anyone able to provide a working test stream to help us validate support?
  • Your evaluation of what should and should not be an out of the box feature is dubious. On what basis did you reach your conclusion, other than it's a feature you personally want?

@Schizo
Copy link

Schizo commented Apr 2, 2015

@ojw28 wheni was writing my comment, i asked my selfe the same question. But to answer your question, h264 streaming over http/udp is one of the most used cases. Nearly every surveillance system i came across was using h264 over http.

For the test-case:
-) What do you need exactly? Can you not test it with an ffmpeg stream easily sending an elementary H264 Stream?

@ojw28
Copy link
Contributor

ojw28 commented Apr 7, 2015

Ideally just a test URL, that works, without us having to spend any time setting one up ourselves.

@ojw28
Copy link
Contributor

ojw28 commented Apr 7, 2015

One other question - Am I correct in thinking that you shouldn't expect seeking to work for this use case (since there's no index, either in the form of an external manifest or in the media stream itself)?

@ojw28
Copy link
Contributor

ojw28 commented Apr 13, 2015

We pushed a bunch of changes that should make this quite straightforward to do. But we're not going to prioritize the work without someone providing a test stream. If no-one is able to do so, then that really indicates that this feature isn't in significant demand.

@Schizo
Copy link

Schizo commented Apr 22, 2015

ojw28 i am ready to setup a wowza test-streaming for 30days, would this be ok?

@ojw28
Copy link
Contributor

ojw28 commented Apr 22, 2015

Just to check: This really is over HTTP and not RTSP right? If so then yes, if you set something up we'll take a look (no promises, since you never know what you'll find when you start trying to build something!).

@Schizo
Copy link

Schizo commented Jul 19, 2015

@ojw28 would it be easier, when i create a plain UDP connection? But then this would be a point-to-point connection and you need to pass me an ip. Where is the depacketization process in exoplayer happening?

@ojw28
Copy link
Contributor

ojw28 commented Jul 20, 2015

We have a UDP data source already as it happens. We'll push it to GitHub in the next week or so. I'm not sure whether it makes this easier or not. I suspect you really want RTSP, which we're not supporting.

@Schizo
Copy link

Schizo commented Jul 20, 2015

UDP is much more important for me then RTSP right now. Any Chance getting the UDP Data source before friday? I can test it as well before it goes to master and give some feedback.

@ojw28
Copy link
Contributor

ojw28 commented Jul 21, 2015

A UdpDataSource is now in dev.

@ojw28 ojw28 closed this as completed Jul 21, 2015
@ojw28 ojw28 reopened this Jul 21, 2015
@Schizo
Copy link

Schizo commented Jul 22, 2015

Thank you for the early package!

Somehow i am getting an Exception "Unexpected Exception loading stream"

What i did:

  1. checked out exoplayer-dev

  2. In demo > PlayerActivity

contentUri = Uri.parse("192.168.1.5:1234");
contentType = TYPE_MP4;
case TYPE_MP4:
return new ExtractorRendererBuilder(this, userAgent, contentUri);
  1. In ExtractorRenderBuilder
DataSource dataSource1 = new UdpDataSource(bandwidthMeter, 2000);
ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri, dataSource1, allocator,
BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE);
  1. I am Streaming from ffmpeg :
    ffmpeg -f avfoundation -i "1:0" -r 30 -vf scale=1280:720 -vcodec libx264 -crf 12 -preset ultrafast -tune zerolatency -threads 8 -thread_type slice -f mpegts udp://192.168.1.5:1234

And i can see the stream it in other players like MxPlayer on my mobile device.

@ojw28
Copy link
Contributor

ojw28 commented Jul 22, 2015

  • We need more information to be able to debug this. Like the stack trace.
  • Why does your code reference MP4 anywhere? I don't think what you're streaming is MP4. What does that ffmpeg command actually cause to be streamed (my guess is MPEG-TS, but I'm unsure)?

@Schizo
Copy link

Schizo commented Jul 22, 2015

  1. LogCat:
07-22 09:13:06.481  14155-14155/? I/ExoPlayerImpl﹕ Init 1.4.1
07-22 09:13:06.485  14155-14155/? D/EventLogger﹕ start [0]
07-22 09:13:06.487  14155-14155/? D/EventLogger﹕ state [0.00, false, P]
07-22 09:13:06.503  14155-14155/? D/EventLogger﹕ state [0.02, true, I]
07-22 09:13:06.545  14155-14155/? D/EventLogger﹕ state [0.06, true, P]
07-22 09:13:06.574      451-476/? I/ActivityManager﹕ Displayed com.google.android.exoplayer.demo/.PlayerActivity: +151ms
07-22 09:13:06.575      816-816/? I/Keyboard.Facilitator﹕ onFinishInput()
07-22 09:13:06.842      153-153/? W/SurfaceFlinger﹕ couldn't log to binary event log: overflow.
07-22 09:13:22.157  14155-14191/? E/LoadTask﹕ Unexpected exception loading stream
    java.lang.IllegalArgumentException
            at com.google.android.exoplayer.util.Assertions.checkArgument(Assertions.java:39)
            at com.google.android.exoplayer.util.ParsableByteArray.setPosition(ParsableByteArray.java:116)
            at com.google.android.exoplayer.util.ParsableByteArray.skipBytes(ParsableByteArray.java:127)
            at com.google.android.exoplayer.extractor.ts.TsExtractor.read(TsExtractor.java:155)
            at com.google.android.exoplayer.extractor.ExtractorSampleSource$ExtractingLoadable.load(ExtractorSampleSource.java:722)
            at com.google.android.exoplayer.upstream.Loader$LoadTask.run(Loader.java:209)
            at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)
07-22 09:13:22.683      451-558/? E/WifiStateMachine﹕ WifiStateMachine CMD_START_SCAN source -2 txSuccessRate=0.25 rxSuccessRate=145.49 targetRoamBSSID=any RSSI=-57
07-22 09:13:28.433      451-558/? E/WifiStateMachine﹕ WifiStateMachine CMD_START_SCAN source -2 txSuccessRate=0.31 rxSuccessRate=183.37 targetRoamBSSID=any RSSI=-58
07-22 09:13:30.734  14155-14191/? E/LoadTask﹕ Unexpected exception loading stream
    java.lang.IllegalArgumentException
            at com.google.android.exoplayer.util.Assertions.checkArgument(Assertions.java:39)
            at com.google.android.exoplayer.util.ParsableByteArray.setPosition(ParsableByteArray.java:116)
            at com.google.android.exoplayer.util.ParsableByteArray.skipBytes(ParsableByteArray.java:127)
            at com.google.android.exoplayer.extractor.ts.TsExtractor.read(TsExtractor.java:155)
            at com.google.android.exoplayer.extractor.ExtractorSampleSource$ExtractingLoadable.load(ExtractorSampleSource.java:722)
            at com.google.android.exoplayer.upstream.Loader$LoadTask.run(Loader.java:209)
            at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)
07-22 09:13:40.981  14155-14191/? E/LoadTask﹕ Unexpected exception loading stream
    java.lang.IllegalArgumentException
            at com.google.android.exoplayer.util.Assertions.checkArgument(Assertions.java:39)
            at com.google.android.exoplayer.util.ParsableByteArray.setPosition(ParsableByteArray.java:116)
            at com.google.android.exoplayer.util.ParsableByteArray.skipBytes(ParsableByteArray.java:127)
            at com.google.android.exoplayer.extractor.ts.TsExtractor.read(TsExtractor.java:155)
            at com.google.android.exoplayer.extractor.ExtractorSampleSource$ExtractingLoadable.load(ExtractorSampleSource.java:722)
            at com.google.android.exoplayer.upstream.Loader$LoadTask.run(Loader.java:209)
            at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)
  1. I am not really referencing mp4, it was just the case statement from my previous code, the dev code furthermore is not passing any specific extractor like mp4Extrator when calling ExtractorRenderBuilder anymore.

@algrid
Copy link

algrid commented Dec 18, 2015

I'm trying to play an MPEG2TS over HTTP stream (I added an entry with my video stream to the Demo app and it's played as DefaultUriDataSource). It starts playing but very often gets stuck with the same error:

12-18 19:09:07.820 24333-24412/com.google.android.exoplayer.demo E/LoadTask: Unexpected exception loading stream
                                                                             java.lang.IllegalArgumentException
                                                                                 at com.google.android.exoplayer.util.Assertions.checkArgument(Assertions.java:39)
                                                                                 at com.google.android.exoplayer.util.ParsableByteArray.setPosition(ParsableByteArray.java:116)
                                                                                 at com.google.android.exoplayer.util.ParsableByteArray.skipBytes(ParsableByteArray.java:127)
                                                                                 at com.google.android.exoplayer.extractor.ts.TsExtractor.read(TsExtractor.java:146)
                                                                                 at com.google.android.exoplayer.extractor.ExtractorSampleSource$ExtractingLoadable.load(ExtractorSampleSource.java:753)
                                                                                 at com.google.android.exoplayer.upstream.Loader$LoadTask.run(Loader.java:209)
                                                                                 at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
                                                                                 at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                                                                                 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                                                                                 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                                                                                 at java.lang.Thread.run(Thread.java:818)

@ernhelm
Copy link

ernhelm commented Dec 18, 2015

Try buffering for 2 to 3 sec twice before playing and allow the buffer to
jump way ahead of the device that streams
On 18 Dec 2015 11:23, "algrid" notifications@github.com wrote:

I'm trying to play an MPEG2TS stream (I added an entry with my video
stream to the Demo app and it's played as DefaultUriDataSource). It starts
playing but very often gets stuck with the same error:

12-18 19:09:07.820 24333-24412/com.google.android.exoplayer.demo E/LoadTask: Unexpected exception loading stream
java.lang.IllegalArgumentException
at com.google.android.exoplayer.util.Assertions.checkArgument(Assertions.java:39)
at com.google.android.exoplayer.util.ParsableByteArray.setPosition(ParsableByteArray.java:116)
at com.google.android.exoplayer.util.ParsableByteArray.skipBytes(ParsableByteArray.java:127)
at com.google.android.exoplayer.extractor.ts.TsExtractor.read(TsExtractor.java:146)
at com.google.android.exoplayer.extractor.ExtractorSampleSource$ExtractingLoadable.load(ExtractorSampleSource.java:753)
at com.google.android.exoplayer.upstream.Loader$LoadTask.run(Loader.java:209)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)


Reply to this email directly or view it on GitHub
#90 (comment).

@algrid
Copy link

algrid commented Dec 22, 2015

Increasing buffer time didn't help.

Investigating further I can see that it looks like TS packets synchronisation problem. For some reason TsExtractor sometimes gets a broken TS packet (with wrong length != 188) and all the following packets are shifted. So it keeps getting packets that aren't starting with SYNC_BYTE (0x47) and ignore them. Sometimes it can by chance receive a packet that's still broken but starting with 0x47 and this can lead to the exception above.

I'm not sure who's to blame, maybe it's even a server side problem, but anyway I'll try to add a resync procedure that will restore normal flow of packets (skipping only 1 or 2 of them).

@sreenadhkondru
Copy link

On the server side, if FFMPEG is being used to stream TS packets on UDP, add the following parameters:
-flush_packets 0
?pkt_size=1316

This will ensure that a TS packet is not spread across 2 UDP packets and a UDP packet loss doesn't trigger the TSExtractor to get an incomplete TS packet and go out of sync. (note that 1316 is a multiple of the TS packet size-188)

On the client side the fix by algrid works.

@lcksk
Copy link

lcksk commented Aug 11, 2016

@ojw28 Do you have a demo for mpeg2ts over UDP (test case for UdpDataSource)?

@ojw28
Copy link
Contributor

ojw28 commented Aug 23, 2016

Closing due to staleness. We do not have a demo for mpeg2ts over UDP. Our handling of UDP is very much a "best effort", as opposed to being a primary use case that we support.

@ojw28 ojw28 closed this as completed Aug 23, 2016
@google google locked and limited conversation to collaborators Aug 23, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants