google / ExoPlayer

This project is deprecated and stale. The latest ExoPlayer code is available in https://github.com/androidx/media
https://developer.android.com/media/media3/exoplayer
Apache License 2.0
21.74k stars 6.03k forks source link

save video to storage when streaming with exoplayer #8574

Closed moradi-morteza closed 3 years ago

moradi-morteza commented 3 years ago

I am using ExoPlayer in android and steaming a [hls] video source. now I want to save this video At the same time as it play on exoplayer. I do not want to use another thread or port or channel like FFMPEG, because its create more than one connection to video source and use more internet Is there a way to do this? Thanks.

marcbaechinger commented 3 years ago

In general you can use a CacheDataSource for caching what is downloaded when playing media. This just stores the data in a a cache and if it is requested again, then it is served from the cache than from the network. This is fairly easy for progressive media. However, when using HLS this gets a bit more difficult I think.

Firstly, an HLS video consists of a (text) playlist and possible multiple tracks and segments. I think that is what you mean when you say 'create more than one connection to video source'. You still can not simply save this into one or several files, which would probably work for a mp4 file, which you probably would be able to do with a TeeDataSource.

The approach with a CacheDataSource described above works for HLS in case it is not an adaptive stream. But adaptive streaming is actually a bit of the point of using HLS so I think your stream is possibly adaptive. This means that the adaptive track selector of ExoPlayer does choose the quality best suited to the current network conditions when doing playback. The track selection decisions of playback A of an HLS stream is very likely to be different with playback B at another time (or even network). You can work around this problem by telling ExoPlayer's track selector to only use a single track by setting the MediaItem.streamKeys accordingly. But with this, your playback is not adaptive anymore which may hurt user experience, something you probably want to avoid.

If you want to give me a more specific answer, you may want to post a sample HLS url that you are using. I can look into it regarding being adaptive, segmented and the like. Happy to help some further.

Oh, and in case you don't really value the feature 'while it is playing', you may want to look into downloading media in the dev guide: https://exoplayer.dev/downloading-media.html

moradi-morteza commented 3 years ago

thanks in my case source is not a play list or multi track its just a single url that Exoplayer use it for play. for example : http://38.99.146.185:7777/PMCMusic/PMCMusic_LR.m3u8

if I want to save and stream this video in same time when click a button, one way is : play link with Exaplayer to see video - then use FFMPEG library to download that link. in this case exoplayer play video and ffmpeg save video in same time in another thread. but exoplayer has own connection to source also ffmpeg has own connection to source, so we have 2 connection to source then mobile use more internet.

I think best way is : force Exoplayer to play video with specific low quality and in same time save it in storage. I am working on this idea but still not complete does it better way?

marcbaechinger commented 3 years ago

When trying to download the playlist from http://38.99.146.185:7777/PMCMusic/PMCMusic_LR.m3u8 the connection times out.

If it is acceptable for you to restrict to a low quality variant then using a CacheDataSource works. That's probably the easiest way in that case.