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

Add network cache functionality to video_player #28094

Open
nagoya0 opened this issue Feb 18, 2019 · 77 comments
Open

Add network cache functionality to video_player #28094

nagoya0 opened this issue Feb 18, 2019 · 77 comments
Labels
new feature p: first party p: video_player P4 passed first triage plugin

Comments

@nagoya0
Copy link

@nagoya0 nagoya0 commented Feb 18, 2019

Steps to Reproduce

I built this sample:

https://github.com/flutter/plugins/tree/master/packages/video_player/example
(v0.10.0+2)

and switched tab from side to side. Downloaded videos are disappear and started redownloading every time.

Flutter Doctor

[√] Flutter (Channel beta, v0.11.10, on Microsoft Windows [Version 10.0.17763.316], locale ja-JP)
    • Flutter version 0.11.10 at C:\flutter
    • Framework revision c27c4a265e (3 months ago), 2018-11-26 17:07:24 -0500
    • Engine revision eebc6a5895
    • Dart version 2.1.0 (build 2.1.0-dev.9.4 f9ebf21297)

[√] Android toolchain - develop for Android devices (Android SDK 28.0.3)
    • Android SDK at C:\Users\XXXXXXXX\AppData\Local\Android\sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-28, build-tools 28.0.3
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1248-b01)
    • All Android licenses accepted.

[√] Android Studio (version 3.3)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin version 33.0.1
    • Dart plugin version 182.5215
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1248-b01)

[√] Connected device (1 available)
    • Pixel 3 • XXXXXXXXX • android-arm64 • Android 9 (API 28)

• No issues found!
@zoechi zoechi added new feature plugin p: first party p: video_player labels Feb 18, 2019
@zoechi zoechi added this to the Goals milestone Feb 18, 2019
@Agraphie
Copy link

@Agraphie Agraphie commented May 22, 2019

Is there any intermediate solution for this problem? Otherwise any app which uses videos will drain your data volume quite fast.

@ohjs88
Copy link

@ohjs88 ohjs88 commented Aug 6, 2019

I cached the data by adding some code as shown below.
(I modified video_player 0.10.1+6.)

VideoPlayerPlugin.java

Added code


    private static SimpleCache sDownloadCache;

    class CacheDataSourceFactory implements DataSource.Factory {
      private final Context context;
      private final DefaultDataSourceFactory defaultDatasourceFactory;
      private final long maxFileSize, maxCacheSize;

      CacheDataSourceFactory(Context context, long maxCacheSize, long maxFileSize) {
        super();
        this.context = context;
        this.maxCacheSize = maxCacheSize;
        this.maxFileSize = maxFileSize;
        //String userAgent = Util.getUserAgent(context, context.getString("ExoPlayer"));
        DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
        defaultDatasourceFactory = new DefaultDataSourceFactory(this.context, bandwidthMeter,
            new DefaultHttpDataSourceFactory("ExoPlayer", bandwidthMeter,DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS, DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS,true));
      }

      @Override
      public DataSource createDataSource() {
        LeastRecentlyUsedCacheEvictor evictor = new LeastRecentlyUsedCacheEvictor(maxCacheSize);
        
        if (sDownloadCache == null) {
            sDownloadCache = new SimpleCache(context.getCacheDir(),evictor);
        }

        return new CacheDataSource(sDownloadCache, defaultDatasourceFactory.createDataSource(), new FileDataSource(),
            new CacheDataSink(sDownloadCache, maxFileSize),
            CacheDataSource.FLAG_BLOCK_ON_CACHE | CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR, null);
      }
    }

Modified code


 if (isFileOrAsset(uri)) {
        dataSourceFactory = new DefaultDataSourceFactory(context, "ExoPlayer");
      } else {
        // dataSourceFactory = new DefaultHttpDataSourceFactory("ExoPlayer", null,
        //     DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS, DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS,
        //     true);
        dataSourceFactory = new CacheDataSourceFactory(context, 100 * 1024 * 1024, 5 * 1024 * 1024);
      }

See the url below.

@lifenautjoe
Copy link

@lifenautjoe lifenautjoe commented Sep 3, 2019

Any other way so far that doesn't involve monkey-patching the library? And that works for iOS as well?

@lifenautjoe
Copy link

@lifenautjoe lifenautjoe commented Sep 3, 2019

Here's a plugin for the iOS AV player that might help. https://github.com/vitoziv/VIMediaCache

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Sep 20, 2019

I need video caching as well, iOS and Android with video_player, does anyone have time to put this together? Use case is a Instagram Stories type of interface where users will progress slowly through videos but reverse quickly. Even if we could get video_player to cache the first 10 seconds that would be fine, just enough to give it time to buffer again.

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Sep 20, 2019

@ohjs88 Can you make a PR against video_player for your cached android code? Do you happen to have iOS code as well?

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Sep 20, 2019

Is it possible to get the file out of video_player and save it to disk with Dart code? Not sure if that's obscene or not.

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Sep 20, 2019

Has anyone tried caching the loaded VideoPlayerControllers in Dart?

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Sep 21, 2019

I tried that out and it does work but you end up with some strange behavior. The app runs out of memory real quick.

@lifenautjoe
Copy link

@lifenautjoe lifenautjoe commented Sep 21, 2019

For what's worth, @999eagle got caching working on both iOS and android on a custom fork of the plugins repository video_player. We hope to open a PR with this back into the plugins repo at some point.

  video_player:
    git:
      url: https://github.com/999eagle/plugins.git
      ref: feature/caching
      path: packages/video_player

Limit is set to 200mbs

Here are the commits with the magic.

https://github.com/999eagle/plugins/commits/feature/caching

Thanks to her work, we've now got video playing in our app :-)

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Sep 21, 2019

@lifenautjoe Thanks for the heads up, is there any reason why there hasn't been a PR back to flutter/plugins ?

@lifenautjoe
Copy link

@lifenautjoe lifenautjoe commented Sep 21, 2019

We're busy with post release activities 😬 , we just got this working a couple days back. We'll PR it back ASAP.

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Sep 21, 2019

Much appreciated for the updates, I'm going to watch that repo for movement/PR. Congrats on the launch!

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Sep 21, 2019

@lifenautjoe Do you guys have a commit cherry picked? This branch appears to not load a .mov file over network that otherwise works with video_player: ^0.10.2+1

Video in question: https://firebasestorage.googleapis.com/v0/b/skatex-8d802.appspot.com/o/test%2Ftest.mov?alt=media&token=a59686ca-09cc-4be4-ba70-5069b3c42da7

For some reason the feature/caching branch doesn't like the URL

When running on XCode these are the logs

2019-09-21 18:08:27.812871-0400 Runner[5519:1637802] flutter: Observatory listening on http://127.0.0.1:57074/-yBssRMosLw=/

2019-09-21 18:08:28.280307-0400 Runner[5519:1637790] flutter: VideoPlayerValue(duration: null, size: null, position: 0:00:00.000000, buffered: [], isPlaying: false, isLooping: false, isBuffering: falsevolume: 1.0, errorDescription: null)

2019-09-21 18:08:28.280977-0400 Runner[5519:1637790] flutter: VideoPlayerValue(duration: null, size: null, position: 0:00:00.000000, buffered: [], isPlaying: true, isLooping: false, isBuffering: falsevolume: 1.0, errorDescription: null)

2019-09-21 18:08:28.384399-0400 Runner[5519:1637782] Task .<1> finished with error - code: -1002

2019-09-21 18:08:28.386857-0400 Runner[5519:1637781] Task .<1> load failed with error Error Domain=NSURLErrorDomain Code=-1002 "unsupported URL" UserInfo={NSLocalizedDescription=unsupported URL, NSErrorFailingURLStringKey=a59686ca-09cc-4be4-ba70-5069b3c42da7, NSErrorFailingURLKey=a59686ca-09cc-4be4-ba70-5069b3c42da7, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask .<1>"
), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask .<1>, NSUnderlyingError=0x2821c0210 {Error Domain=kCFErrorDomainCFNetwork Code=-1002 "(null)"}} [-1002]

2019-09-21 18:08:28.453100-0400 Runner[5519:1637790] flutter: VideoPlayerValue(duration: null, size: null, position: 0:00:00.000000, buffered: [], isPlaying: false, isLooping: false, isBuffering: falsevolume: 1.0, errorDescription: Failed to load video: unsupported URL)

@lifenautjoe
Copy link

@lifenautjoe lifenautjoe commented Sep 21, 2019

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Sep 22, 2019

I did get it to work, and the caching works beautifully. However, there are still some strange issues.

This video & URL works. http://techslides.com/demos/sample-videos/small.mp4

Copied to my host, this URL fails. https://firebasestorage.googleapis.com/v0/b/skatex-8d802.appspot.com/o/test%2Fsmall.mp4?alt=media&token=82cdf4a4-78e4-46e6-a6ab-8456f7f0a0eb

Using Dart URI encoding, it also fails Uri.encodeFull("https://firebasestorage.googleapis.com/v0/b/skatex-8d802.appspot.com/o/test%2Fsmall.mp4?alt=media&token=82cdf4a4-78e4-46e6-a6ab-8456f7f0a0eb")

That method produces this link https://firebasestorage.googleapis.com/v0/b/skatex-8d802.appspot.com/o/test%252Fsmall.mp4?alt=media&token=82cdf4a4-78e4-46e6-a6ab-8456f7f0a0eb

Percent encoded (using https://www.url-encode-decode.com), it works. https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fskatex-8d802.appspot.com%2Fo%2Ftest%252Fsmall.mp4%3Falt%3Dmedia%26token%3D82cdf4a4-78e4-46e6-a6ab-8456f7f0a0eb

Not sure if this is helpful, but I did see some mention to percent encoding here https://stackoverflow.com/questions/11362153/bad-url-error-with-nsurlrequest

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Sep 22, 2019

Another case....

This works on the pub.dev version of video_player but fails on the feature/caching version

https://firebasestorage.googleapis.com/v0/b/skatex-8d802.appspot.com/o/test%2Ftest-Broadband%20Low.mp4?alt=media&token=00f64abd-c552-4d7b-a964-72a22811722f

However, it will not play on either as a percent encoded url
https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fskatex-8d802.appspot.com%2Fo%2Ftest%252Ftest-Broadband%2520Low.mp4%3Falt%3Dmedia%26token%3D00f64abd-c552-4d7b-a964-72a22811722f

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Sep 22, 2019

Alright, I got it working by encoding the URL with this line. It seems heavy handed but I'm getting good results.

NSString *escapedURL = [uriArg stringByAddingPercentEncodingWithAllowedCharacters:NSMutableCharacterSet.alphanumericCharacterSet];

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Sep 22, 2019

Pull request: 999eagle/plugins@ed5e865

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Sep 23, 2019

@lifenautjoe @999eagle just got to it and VideoPlayerController.file() does not work on iOS on 999eagle/plugins/video_player @ feature/caching. Any insights?

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Sep 25, 2019

I believe this makes feature/caching ready for PR on iOS. I haven't tried Android yet

999eagle/plugins#2

@recastrodiaz
Copy link

@recastrodiaz recastrodiaz commented Oct 4, 2019

I have an alternative video networking caching implementation if anyone is interested in using it:

flutter/plugins@master...recastrodiaz:develop2

It has other features as well like:

  • audio focus
  • clipping videos
  • playback speed feature
  • fixes some videos showing a black screen on iOS
  • more recent ExoPlayer
  • load videos from phAssets on iOS

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Oct 5, 2019

I’m going to check it out because you’ve added some features I need myself. Will you be making a PR against video_player? Is it cross platform?

@omidraha
Copy link

@omidraha omidraha commented Apr 29, 2021

I have same issue and currently use flutter_cache_manager ,
Here is my sample code:

Bloc:

      yield PlayerIsLoading();
      String url = 'sample video url';
      try {
        file = await userRepository.getFileAPI(url);
      } on ServerConnectionFailed catch (e) {
        yield ServerIsNotAvailable(
            networkMessage: e.message,
        );
        return;
      }

      VideoPlayerController videoPlayerController =
          VideoPlayerController.file(file);

      yield PlayerLoaded(
        videoPlayerController: videoPlayerController,
      );
    }

userRepository:

  Future<File> getFileAPI(String url) async {
    File file;
    try {
      file = await DefaultCacheManager().getSingleFile(url).timeout(
            Duration(seconds: SocketTimeOut),
          );
    } on HttpException catch (e) {
      throw ServerConnectionFailed(
        message: ServerConnectionFailed.defaultMessage,
      );
    } on TimeoutException catch (e) {
      throw ServerConnectionFailed(
        message: ServerConnectionFailed.defaultMessage,
      );
    } on SocketException catch (e) {
      throw ServerConnectionFailed(
        message: ServerConnectionFailed.defaultMessage,
      );
    }
    return file;
  }

Note:
The CacheManager package by default download old file again (after 30 day), this is not suitable for videos file you know there is no change in lifetime of them.

@b3nni97
Copy link

@b3nni97 b3nni97 commented Jul 27, 2021

Is anyone currently working on a solution? Caching is a critical feature for many apps

@JonasJW
Copy link

@JonasJW JonasJW commented Jul 27, 2021

@b3nni97 check out the better_player plugin, it solved my video caching problems

@amalnaami
Copy link

@amalnaami amalnaami commented Aug 9, 2021

@b3nni97 check out the better_player plugin, it solved my video caching problems

It doesn't solve the problem
there is any new suggestion to cache video from network ??

@b3nni97
Copy link

@b3nni97 b3nni97 commented Aug 9, 2021

I think the only thing that helps is to wait until many people become aware of the problem so that something happens.
The current video player is also not very efficient when you want to display multiple videos in a ListView. I haven't found an approach that works yet. (there are lags etc)

@sanekyy
Copy link

@sanekyy sanekyy commented Aug 9, 2021

@b3nni97
Hello. For this case you can try to use my old PR with reusable video player:)
flutter/plugins#2406

@b3nni97
Copy link

@b3nni97 b3nni97 commented Aug 9, 2021

@sanekyy
Thanks for the tip. The problem is that such pull requests should be merged. I see the problem is due to an unsigned CLA. I would be very grateful if you could catch up on this, because this is a critical feature (for me at least).

I think that such basic features should be supported by default in the video player.

@amalnaami
Copy link

@amalnaami amalnaami commented Aug 10, 2021

I wondered if we can stream video Url that come from back using Flutter code ?

@sanekyy
Thanks for the tip. The problem is that such pull requests should be merged. I see the problem is due to an unsigned CLA. I would be very grateful if you could catch up on this, because this is a critical feature (for me at least).

I think that such basic features should be supported by default in the video player.

@kamlesh1687
Copy link

@kamlesh1687 kamlesh1687 commented Sep 11, 2021

I think the only thing that helps is to wait until many people become aware of the problem so that something happens.
The current video player is also not very efficient when you want to display multiple videos in a ListView. I haven't found an approach that works yet. (there are lags etc)

You can use Flick player ,they have implemented their own way for playing videos in feed

@Leffe108
Copy link

@Leffe108 Leffe108 commented Dec 15, 2021

@Gicminos I use flutter_cache_manager with video_player. In my case I am often able to know ahead of time which video to play ahead of time so I can trigger download to cache. Thus in many cases I avoid duplicate downloads and this solution works quite well. It also helps in my case that the videos are rather short.

To give a bit more context the app is a quiz app and when user start to answer one question, I generate the next one and load video clips for the next one while user is responding to the current question. Usually the user is slower. :-)

@mavericksunny
Copy link

@mavericksunny mavericksunny commented Dec 28, 2021

https://github.com/mavericksunny/plugins/commits/caching

@sanekyy Ive forked your repository and updated it with the latest video player master repo. Took me a while to resolve the conflicts, but it seems to work now.
For anyone who wants to use it, you can use this as a dependency:

video_player:
git:
url: git@github.com:mavericksunny/plugins.git
ref: caching
path: packages/video_player/video_player

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Dec 28, 2021

@mavericksunny open a PR if you have it working and up to date with main branch, maybe we can get this merged once and for all

@sanekyy
Copy link

@sanekyy sanekyy commented Dec 28, 2021

@mavericksunny
Great!
Link PR here if you'll open

@aytunch
Copy link

@aytunch aytunch commented Dec 29, 2021

I hope it is working as intended and gets approved. This can be a huge improvement for video driven apps.

@mavericksunny
Copy link

@mavericksunny mavericksunny commented Dec 29, 2021

@sanekyy Ive opened it against your repo: sanekyy/plugins#5
Also can you merge the latest master from flutter plugins? To avoid seeing the complete diff.

sanekyy/plugins@677d928

@marcusrohden
Copy link

@marcusrohden marcusrohden commented Jan 17, 2022

@sanekyy Ive opened it against your repo: sanekyy/plugins#5 Also can you merge the latest master from flutter plugins? To avoid seeing the complete diff.

sanekyy/plugins@677d928

hey guys, any updates on this? the caching feature would be amazing to have.
thx!

@ciriousjoker
Copy link

@ciriousjoker ciriousjoker commented Feb 6, 2022

We ended up using DefaultCacheManager() to download the video before displaying it.
This does work, but the drawback is obvious. The whole video is downloaded before displaying a single frame, which is terrible UX. The alternative would have been to stream the video first and cache it in the background, which would download the whole thing twice.

Please add caching to video_player so we can remove our custom caching logic and stream the files directly without caching first or downloading it twice.

@aytunch
Copy link

@aytunch aytunch commented Feb 6, 2022

In our app we have a video feed and we are preloading 2-3 videos ahead of time which makes the bandwidth usage even worse with the current video_player implementation. If there were caching support, the feed would have been much more memory, performance and bandwidth effective which would result in better user feedback..

Please up-vote the issue so this takes into consideration with a higher priority.

@b3nni97
Copy link

@b3nni97 b3nni97 commented Feb 6, 2022

I also don't understand why nothing happens here. Caching is essential especially in the mobile area where bandwidth and memory are relatively scarce.

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Feb 7, 2022

@TahaTesser Sorry to ping, not sure who to ask. Is this the type of feature that should have a doc written up first? Would appreciate some guidance (ideally Googler sponsor) before investing time into this. Don't want a repeat of the last time the community attempted to land this

@TahaTesser
Copy link
Member

@TahaTesser TahaTesser commented Feb 7, 2022

cc: @stuartmorgan
Could you please provide some guidance #28094 (comment)

@stuartmorgan
Copy link
Contributor

@stuartmorgan stuartmorgan commented Feb 7, 2022

Is this the type of feature that should have a doc written up first?

It certainly never hurts to have a design document for a non-trivial PR.

Don't want a repeat of the last time the community attempted to land this

My understanding is that the primary issue last time was that the PR went unreviewed for a very long time. That should no longer happen, as flutter/plugins PRs now follow the same triage policy as the other Flutter repositories, meaning we are regularly checking in with all open PRs.

@lukepighetti
Copy link

@lukepighetti lukepighetti commented Feb 7, 2022

Is there anyone in particular who should be pinged when a design doc is ready for this type of feature?

@stuartmorgan
Copy link
Contributor

@stuartmorgan stuartmorgan commented Feb 7, 2022

Posting it here and in #hackers-ecosystem in Discord would probably be the best way to ensure people see it.

@victor-tinoco

This comment was marked as off-topic.

@stuartmorgan
Copy link
Contributor

@stuartmorgan stuartmorgan commented Feb 15, 2022

Please see https://github.com/flutter/flutter/wiki/Issue-hygiene#when-will-my-bug-be-fixed

(And as noted there, please do not comment to say that you want the feature; doing so is not productive, and spams everyone who is subscribed to the issue.)

@iosephmagno

This comment was marked as off-topic.

@khater277
Copy link

@khater277 khater277 commented Apr 26, 2022

@mavericksunny .file not work correctly it gives me that error in initialize [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: PlatformException(NullPointerException, java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference, null, null)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new feature p: first party p: video_player P4 passed first triage plugin
Projects
None yet
Development

No branches or pull requests