Codename one video crashing on iOS when fast foward/ reverse button pressed

We have a video supply app written in Codename one.
We are using com.codename1.media.MediaPlayer to show the video full screen using the native player components.
Our client has noticed that when you press the fast forward(>>) button or the reverse button(<<) then the video is kicking you back to the app.

The code which plays the video looks something like this;

...
private Media video;
...
(on EDT:)
InputStream input = {get video InputStream from path}
video = MediaManager.createMedia(input, "video/mp4", this::videoFinished);
video.setFullScreen(true);
video.setNativePlayerMode(true);
.... 
(after pressing the play button:)
if (video.isPlaying()) {
     video.setTime(0);
    video.pause();
}
video.prepare();
video.play();
...
private void videoFinished() {
    {update UI after video has finished}
}

I collected the following log from the console if that helps;

2018-11-01 15:08:38.290366+1300 Main[2000:481106] [] <<<< AVOutputDeviceDiscoverySession (FigRouteDiscoverer) >>>> -[AVFigRouteDiscovererOutputDeviceDiscoverySessionImpl outputDeviceDiscoverySessionDidChangeDiscoveryMode:]: Setting device discovery mode to DiscoveryMode_None (client: Main)
2018-11-01 15:08:39.058905+1300 Main[2000:481106] [] <<<< AVOutputDeviceDiscoverySession (FigRouteDiscoverer) >>>> -[AVFigRouteDiscovererOutputDeviceDiscoverySessionImpl outputDeviceDiscoverySessionDidChangeDiscoveryMode:]: Setting device discovery mode to DiscoveryMode_Presence (client: Main)
2018-11-01 15:09:00.005725+1300 Main[2000:481106] Status bar could not find cached time string image. Rendering in-process.
2018-11-01 15:09:00.144446+1300 Main[2000:481106] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. 
Try this: 
    (1) look at each constraint and try to figure out which you don't expect; 
    (2) find the code that added the unwanted constraint or constraints and fix it. 
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
"<NSAutoresizingMaskLayoutConstraint:0x10eb09790 h=-&- v=-&- _UIBackdropContentView:0x108d4a310.midY == _UIBackdropView:0x108d59fb0.midY   (active)>",
"<NSAutoresizingMaskLayoutConstraint:0x10eb0abd0 h=-&- v=-&- _UIBackdropContentView:0x108d4a310.height == _UIBackdropView:0x108d59fb0.height   (active)>",
"<NSLayoutConstraint:0x10ccf2440 V:|-(0)-[UIStatusBar:0x102922200]   (active, names: '|':_UIBackdropContentView:0x108d4a310 )>",
"<NSLayoutConstraint:0x10ccf24e0 UIStatusBar:0x102922200.height == 20   (active)>",
"<NSLayoutConstraint:0x10ccf2bf0 UIView:0x10cce7e10.top == _UIBackdropView:0x108d59fb0.top + 40   (active)>",
"<NSLayoutConstraint:0x10ccf26e0 V:[UIStatusBar:0x102922200]-(0)-[UIView:0x10cce7e10]   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x10ccf26e0 V:[UIStatusBar:0x102922200]-(0)-[UIView:0x10cce7e10]   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
2018-11-01 15:09:00.687662+1300 Main[2000:481106] [] <<<< AVOutputDeviceDiscoverySession (FigRouteDiscoverer) >>>> -[AVFigRouteDiscovererOutputDeviceDiscoverySessionImpl outputDeviceDiscoverySessionDidChangeDiscoveryMode:]: Setting device discovery mode to DiscoveryMode_None (client: Main)

Everything works correctly on Android.

Edit:

Refactored the code to use file URL's instead of input streams but it still has the same error on iOS

Edit:

This is a problem even when using web urls.
Here is a very simple test case which illustrates the issue;

public class MyApplication {

    private Form current;
    private Resources theme;
    private Media video;

    public void init(Object context) {
        // use two network threads instead of one
        updateNetworkThreadCount(2);

        theme = UIManager.initFirstTheme("/theme");

        // Enable Toolbar on all Forms by default
        Toolbar.setGlobalToolbar(true);

        // Pro only feature
        Log.bindCrashProtection(true);

        addNetworkErrorListener(err -> {
            // prevent the event from propagating
            err.consume();
            if(err.getError() != null) {
                Log.e(err.getError());
            }
            Log.sendLogAsync();
            Dialog.show("Connection Error", "There was a networking error in the connection to " + err.getConnectionRequest().getUrl(), "OK", null);
        });        
    }

    public void start() {
        if(current != null){
            current.show();
            return;
        }
        Form hi = new Form("Hi World", BoxLayout.y());
        //hi.add(new Label("Hi World"));
        Button play = new Button("Play");
        play.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                playVideo();
            }


        });
        hi.add(play);
        hi.show();
    }

    private void playVideo() {
        try {
            String path = getPath();
            video = MediaManager.createMedia(path, true, null);
            video.setFullScreen(true);
            video.setNativePlayerMode(true);

            video.prepare();
            video.play();
        } catch (IOException ex) {
            Log.e(ex);
        }
    }

    private String getPath() {
        return "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4";
    }
    public void stop() {
        current = getCurrentForm();
        if(current instanceof Dialog) {
            ((Dialog)current).dispose();
            current = getCurrentForm();
        }
    }

    public void destroy() {
    }
}

Note: To run this on ios you need to add the security exception to the plistInject build hint. Add this into the codenameone_settings.properties file;

codename1.arg.ios.plistInject=<key>UIRequiresFullScreen</key><true/><key>ITSAppUsesNonExemptEncryption</key><false/><key>NSAppTransportSecurity</key><dict><key>NSExceptionDomains</key><dict><key>commondatastorage.googleapis.com</key><dict><key>NSIncludesSubdomains</key><true/><key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key><true/></dict></dict></dict>
728x90

1 Answers Codename one video crashing on iOS when fast foward/ reverse button pressed

Seeking with an input stream might be a bit problematic as we can't rewind/skip in the stream effectively while communicating with the native layer. That's why we always recommend using the version that accepts a URL as an argument. You can use a file URL which should work well for all platforms.

6 months ago