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

[BUG] Player shows a black screen while playing video on IOS #1029

Open
BTonny opened this issue Jun 12, 2022 · 20 comments · May be fixed by #1115
Open

[BUG] Player shows a black screen while playing video on IOS #1029

BTonny opened this issue Jun 12, 2022 · 20 comments · May be fixed by #1115
Assignees
Labels
new issue New issue which has not been checked yet

Comments

@BTonny
Copy link

BTonny commented Jun 12, 2022

History check
Looking at past issues, someone suggested they experienced the issue but no solution. He suggested its an issue in better_player: ^0.0.81, and suggested a change to 0.0.80 but this doesn't work.

Describe the bug
The player is able to load the network video but only the audio plays. the video doesn't show. All though.

To Reproduce
Ive experienced the issue with a video from network and not quite certain if other types also produce the same. Since my app only uses videos from network.

*Example code

class AppCachedVideoPlayer extends StatefulWidget {
  final String videoPath;
  const AppCachedVideoPlayer({Key? key, required this.videoPath})
      : super(key: key);

  @override
  State<AppCachedVideoPlayer> createState() => _AppCachedVideoPlayerState();
}

class _AppCachedVideoPlayerState extends State<AppCachedVideoPlayer> {
  VideoPlayerController? videoPlayerController;
  BetterPlayerController? _betterPlayerController;
  bool playerLoaded = false;
  double aspectRatio = 0;

  @override
  void initState() {
    if (widget.videoPath.contains("http")) {
      videoPlayerController = VideoPlayerController.network(widget.videoPath);
    } else {
      videoPlayerController =
          VideoPlayerController.file(File(widget.videoPath));
    }
    initializePlayer();
    super.initState();
  }

  initializePlayer() async {
    await videoPlayerController!.initialize();

    setState(() {
      playerLoaded = true;
    });

    BetterPlayerDataSource _betterPlayerDataSource = BetterPlayerDataSource(
      widget.videoPath.contains("http")
          ? BetterPlayerDataSourceType.network
          : BetterPlayerDataSourceType.file,
      widget.videoPath,
      cacheConfiguration: BetterPlayerCacheConfiguration(
        useCache: true,
        preCacheSize: 10 * 1024 * 1024,
        maxCacheSize: 10 * 1024 * 1024,
        maxCacheFileSize: 10 * 1024 * 1024,

        ///Android only option to use cached video between app sessions
        key: widget.videoPath,
      ),
    );

    BetterPlayerConfiguration betterPlayerConfiguration =
        BetterPlayerConfiguration(
      controlsConfiguration: const BetterPlayerControlsConfiguration(
        playIcon: Ionicons.play,
        enableOverflowMenu: false,
        enableSkips: false,
      ),
      aspectRatio: videoPlayerController!.value.aspectRatio,
    );
    _betterPlayerController = BetterPlayerController(
      betterPlayerConfiguration,
      betterPlayerDataSource: _betterPlayerDataSource,
    );
  }

  @override
  void dispose() {
    videoPlayerController?.dispose();
    _betterPlayerController?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return playerLoaded
        ? BetterPlayer(controller: _betterPlayerController!)
        : Container(
            padding: const EdgeInsets.all(10),
            child: const Center(
              child: CircularProgressIndicator(
                  ),
            ),
          );
  }
}

Expected behavior
The video loads and plays but keeps showing a black screen.

Screenshots
Simulator Screen Shot - iPhone 13 - 2022-06-12 at 18 11 20

Flutter doctor

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.10.5, on macOS 12.3.1 21E258 darwin-x64, locale en-GB)
[✓] Android toolchain - develop for Android devices (Android SDK version 32.1.0-rc1)
[✓] Xcode - develop for iOS and macOS (Xcode 13.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.2)
[✓] VS Code (version 1.68.0)
[✓] Connected device (2 available)
[✓] HTTP Host Availability

• No issues found!

Better Player version

  • Version: better_player: ^0.0.81

Smartphone (please complete the following information):

  • iPhone13
  • iOS 15.2
@BTonny BTonny added the new issue New issue which has not been checked yet label Jun 12, 2022
@imranakhtar4848
Copy link

Working on real device. Tested on iPhone 7 plus.

@marioloko
Copy link

Same problem here. With iOS simulator the screen remains black but I can hear the audio as the video progresses.

I have tested different versions of this library. Version 0.0.69 is the highest version that has worked for me, it does not display a black screen but the actual video, so it seems the right behavior.

The steps I followed to try is (in AndroidStudio + Terminal):

# Enter flutter project root in a terminal
flutter clean
# Change version to 0.0.69 in pubspec.yaml and save file
flutter pub get
# Click the play button in Android Studio to compile and run flutter app

I've been looking the changes related to iOS between version 0.0.69 and 0.0.70 and they seem quite a lot, so finding the offending piece of code may take its time. I add the link here in case anyone wants to take a look in parallel.

@marioloko
Copy link

marioloko commented Jun 28, 2022

I dig deeper in every commit between version 0.0.69 and 0.0.70 to find the offending commit. What I found is that 9214d6adf59bdcfbe9b6a6fdca0fd431c95ebcea (Exposed BetterPlayerControlsState to provide ways to build custom controls with additional menus) is the last working commit and 200777060677df2cfcdc2fc9891579d3f0ef3001 (Fairplay ezdrm) is the first not working commit.

Then, the changes that impact on the iOS simulator visualization are those of commit 200777060677df2cfcdc2fc9891579d3f0ef3001 (Fairplay ezdrm).

To reproduce the working commit just add the following to your pubspect.yaml:

  better_player:
    git:
      url: https://github.com/jhomlala/betterplayer.git
      ref: 9214d6adf59bdcfbe9b6a6fdca0fd431c95ebcea

And then, follow the steps of the code snipped in my previous comment.

Here you can find the changes of the offending commit.

This bounds a little more the problem, let's check if we can find the problem with this. :)

@marioloko
Copy link

It seems, that the commit in the previous comment is divided in 15 commits, so I analyzed them and the last subcommit that works is dd0c4e0d4dc2b25510b609e312dfc01aa74a5c5b while the first that do not work is 8697d6bfe30a3117d109ee0ead53b645ee58b5c4. Then, the last one may contains the offending changes.

The changes of this commit can be change here.

Now the problem seems quite bounded and the changes of this commit are small, I can try to roll back those changes in version 0.0.83 just to check if this solves the problem. :)

@marioloko
Copy link

By rolling back the changes I am able to see the video (no black screen) on version 0.0.83. I uploaded the changes to my fork of the repository, so you can try if it is the same problem for you too.

To test with my fork you can use:

  better_player:
    git:
      url: https://github.com/marioloko/betterplayer.git
      ref: master

However, this commit is just for testing purposes, as it just rollbacks some changes without taking into account the implications of that and produces a segmentation faults.

I uploaded the commit just to verify that the problem of other people is caused by the same code, and if so we can focus on fixing that code, so I will be glad if some of you can verify that black screen problem disappears on iOS simulator using my fork.

@koldo92, I see that you are the committer of that code, do you remember what problem it was trying to fix? I see that the changes are related with Fairplay ezdrm, however, I am not sure what concrete problem is targeting the offending commit. I will be really glad if you could guide us a bit about this issue. Thank you in advance for your time 😄

@marioloko
Copy link

Doing some research it seems that the reason of the change is explained in this comment.

So it seems a way to fix black screen problem on Android and iOS by using UIKit instead of Texture on iOS devices, however, this same solution causes iOS simulator to show black screen.

Let's research more to see if it is possible to have both iOS simulator and devices working. 😄

@marioloko
Copy link

marioloko commented Jul 2, 2022

The plugin native_video_view seems to display correctly in the simulator, and its approach is similar to the one used after commit 8697d6bfe30a3117d109ee0ead53b645ee58b5c4. It has a UIView on the iOS side and a UIKitView on the flutter side, so maybe we should try to get ideas of how they build the view. Their implementation of iOS UIView can be found here.

I tried, WITH NO SUCCESS, to replicate their code by adding a create view method in BetterPlayer:

- (void)createView:(CGRect)frame {
    if (_playerView == nil || _playerView == NULL || [_playerView.class isKindOfClass:NSNull.class]) {
       _playerView = [[BetterPlayerView alloc] initWithFrame:frame];
    }
    _playerView.backgroundColor = [UIColor clearColor];
    _playerView.player = _player;
    AVPlayerLayer* playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];

    if (playerLayer != nil) {
        playerLayer.frame = [_playerView bounds];
        playerLayer.videoGravity = AVLayerVideoGravityResize;
        _playerView.layer.sublayers = nil;
        [_playerView.layer addSublayer:playerLayer];
    }
}

And called in BetterPlayerPlugin:

#pragma mark - FlutterPlatformViewFactory protocol
- (NSObject<FlutterPlatformView>*)createWithFrame:(CGRect)frame
                                   viewIdentifier:(int64_t)viewId
                                        arguments:(id _Nullable)args {
    NSNumber* textureId = [args objectForKey:@"textureId"];
    BetterPlayer* player = [_players objectForKey:@(textureId.intValue)];
    [player createView:frame];
    return player;
}

I will continue the research and posting here the things that I find, just in case anyone else wants to help debugging this issue too.

Thank you all! :D

@marioloko
Copy link

marioloko commented Jul 3, 2022

Ok, I have some good news. I am able to visualize videos on iOS simulator just by disabling video composition.

(void)setDataSourcePlayerItem:(AVPlayerItem*)item withKey:(NSString*)key{
...
#if !TARGET_OS_SIMULATOR
                        item.videoComposition = videoComposition;
#endif
...
}

It seems that the iOS simulator is not rendering the image successfully when running on simulator.

Even if this solution fixes the problem I prefer to find a solution which does not branch the behavior if it runs in the simulator. As it can make future bugs harder to debug.

@jhomlala what is the objective of using AVMutableVideoComposition in that part? Is just for changing the preferred transform and width/height? If that is the case maybe it is possible to find an alternative without using AVMutableVideoCompositon.

@marioloko
Copy link

Finally I push a fix to my personal fork of this project. The changes I did can be seen in this commit. I plan to do a pull request to this repository, but only when several people have tested on their simulators and physical devices to verify that I did not break anything. In my iOS simulator and iPhone 11 it works correctly.

The changes introduced by this commit removes the correction of video track transform, that was used previously to fix black screen problems on iOS devices. Contrary to the proposed in my previous comment, I removed the correction for both iOS simulatior and physical device, as my assumption is that the fix was required due to the previous usage of AVPlayerItemOutput to render textures, which it is not needed anymore as UIView and AVPlayerLayer are used instead. So I guess that this fix can benefit both systems, if anyone experiences black screen issues due to my changes tell me to limit the changes only to the iOS simulator.

In order to use my personal fork you can add the following dependency to your pubspec.yaml:

  better_player:
    git:
      url: https://github.com/marioloko/betterplayer.git
      ref: ios-simulator-blackscreen

If you experience any issue with the given solution please tell me to fix it. And if you test it and it works for you, please add a comment about which platform did you run it (iOS simulator, iPhone, iPad), just to verify that the solution works for these platforms.

This solution works for me, so I do not plan to do further research unless any of you find a problem with the proposed solution, in that case I will try to solve the issue. 😄

@BTonny
Copy link
Author

BTonny commented Jul 5, 2022

@marioloko thank you so much for the temporary fix. let me try it out and hope it will work great for me

@marioloko
Copy link

Thank you for testing the solution. Can you comment here if worked fine for you or experience any problem?

@thuanhv1999
Copy link

thuanhv1999 commented Nov 1, 2022

it still doesn't work on 0.0.81 with flutter v2.10.5

@GlaucoMendes
Copy link

@marioloko It worked for me. Any predictions to enter the major version?

@marioloko
Copy link

it still doesn't work on 0.0.81 with flutter v2.10.5

My commit is only committed in my fork, right now it is not available in the main repo.

@marioloko It worked for me. Any predictions to enter the major version?

If it worked for you I will open a pull request to the main repository. But I cannot tell you for sure when it will be accepted.

@marioloko
Copy link

@jhomlala can you accept the pull request to merge the fix to the main branch?

@SamerOrfali22
Copy link

@marioloko have you test it in real device IOS 16+ for .m3u8 videos?
because on 0.0.83 package it's not working, so I'm wondering if it's working in your repo

@marioloko
Copy link

I tested on my iPhone but not for .m3u8 so I can't tell if my repo will work, but you can try pointing to it.

@EtcGonza
Copy link

EtcGonza commented Jun 6, 2023

Finally I push a fix to my personal fork of this project. The changes I did can be seen in this commit. I plan to do a pull request to this repository, but only when several people have tested on their simulators and physical devices to verify that I did not break anything. In my iOS simulator and iPhone 11 it works correctly.

The changes introduced by this commit removes the correction of video track transform, that was used previously to fix black screen problems on iOS devices. Contrary to the proposed in my previous comment, I removed the correction for both iOS simulatior and physical device, as my assumption is that the fix was required due to the previous usage of AVPlayerItemOutput to render textures, which it is not needed anymore as UIView and AVPlayerLayer are used instead. So I guess that this fix can benefit both systems, if anyone experiences black screen issues due to my changes tell me to limit the changes only to the iOS simulator.

In order to use my personal fork you can add the following dependency to your pubspec.yaml:

  better_player:
    git:
      url: https://github.com/marioloko/betterplayer.git
      ref: ios-simulator-blackscreen

If you experience any issue with the given solution please tell me to fix it. And if you test it and it works for you, please add a comment about which platform did you run it (iOS simulator, iPhone, iPad), just to verify that the solution works for these platforms.

This solution works for me, so I do not plan to do further research unless any of you find a problem with the proposed solution, in that case I will try to solve the issue. 😄

I tested this branch in a ios and android simulator and also in a ios and android devices. The fix of the black screen works great, it would be great a release with this fix. The only issue that i found is that the dot of the progress bar doesn't move while the video is playing. It gets stuck. I going to check if this is happening in the actual release.

@rt234cw
Copy link

rt234cw commented Dec 1, 2023

Finally I push a fix to my personal fork of this project. The changes I did can be seen in this commit. I plan to do a pull request to this repository, but only when several people have tested on their simulators and physical devices to verify that I did not break anything. In my iOS simulator and iPhone 11 it works correctly.

The changes introduced by this commit removes the correction of video track transform, that was used previously to fix black screen problems on iOS devices. Contrary to the proposed in my previous comment, I removed the correction for both iOS simulatior and physical device, as my assumption is that the fix was required due to the previous usage of AVPlayerItemOutput to render textures, which it is not needed anymore as UIView and AVPlayerLayer are used instead. So I guess that this fix can benefit both systems, if anyone experiences black screen issues due to my changes tell me to limit the changes only to the iOS simulator.

In order to use my personal fork you can add the following dependency to your pubspec.yaml:

  better_player:
    git:
      url: https://github.com/marioloko/betterplayer.git
      ref: ios-simulator-blackscreen

If you experience any issue with the given solution please tell me to fix it. And if you test it and it works for you, please add a comment about which platform did you run it (iOS simulator, iPhone, iPad), just to verify that the solution works for these platforms.

This solution works for me, so I do not plan to do further research unless any of you find a problem with the proposed solution, in that case I will try to solve the issue. 😄

Thanks for your work.
Btw, am I able to use two refs?
like

better_player:
    git:
      url: https://github.com/matthewrice345/betterplayer.git
      ref: Issue1057
      url: https://github.com/marioloko/betterplayer.git
      ref: ios-simulator-blackscreen

@marioloko
Copy link

I don't think so, because when you use a import a library in your dart code you are importing one version of the code, so with two refs ai think dart will not be able to resolv which version of the code to use.

What do you need to achieve? Two fixes? The solution for that should be to merge both fixes in a single branch, in case the branches do not conflict I do not mind to create a branch merging both branches, but I will not be able to test it, so you will have to test it works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new issue New issue which has not been checked yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants