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

Video playback issues #2442

Closed
mrEuler opened this issue May 23, 2024 · 16 comments · Fixed by #2448 or #2451
Closed

Video playback issues #2442

mrEuler opened this issue May 23, 2024 · 16 comments · Fixed by #2448 or #2451
Labels
bug Something isn't working released

Comments

@mrEuler
Copy link

mrEuler commented May 23, 2024

Description

Just in case moving my comments from #1326
I've tried already video feature today, looks good! Only few things find a bit off:

  1. some videos are rotated incorrectly (portrait becomes landscape)
  2. incorrectly FPS detection (60 fps video is 2x time slower, than it should)
  3. I changed useVideo hook to get the "video" variable outside of that hook, called .seek(t:ms) function with custom scrubber -- only few frames were changed in 10 seconds video. I've also put 'true' value in if statement, where video.nextImage(); is executed. Also quick check, if I make with ffmpeg video all frames being keyframes -- I can scrub back and forward.
    BUT!: After draging here and there app can rendomly crash (android logs point on skia)

Anyway waiting for the new version! If scrubbing on Android will work, this going to be killer feature to use this, instead of RNVideo!

Thanks!

Version

1.3.0

Steps to reproduce

Some issues are random, but everything is in the description

Snack, code example, screenshot, or link to a repository

Standard example from website can show this issues.

@mrEuler mrEuler added the bug Something isn't working label May 23, 2024
@mrEuler
Copy link
Author

mrEuler commented May 24, 2024

Maybe something like this can be achieved using some flag, when needed?
google/ExoPlayer#2191 (comment)

@mrEuler
Copy link
Author

mrEuler commented May 24, 2024

@wcandillon ^^

@wcandillon
Copy link
Collaborator

I've fixed the framerate issue, now looking into exposing/testing the seek command.

About the rotation, do you believe that there is some metadata that should be read and isn't? could you provide a sample video file to test?

@wcandillon
Copy link
Collaborator

I can confirm that seek seems to work as expected, but please let me know if you have more test cases for me. I'm also interested about the orientation issue.

@mrEuler
Copy link
Author

mrEuler commented May 28, 2024

@wcandillon Thanks!
Is there a possibility to have currentTime property as a sharedValue?
For the rotation will send you today.
For the seeking -- RNVideo is able to extract the preview every second of the video, with Skia I was able to do that only every 5~ seconds. Will send you that as well. I was able to test only on android.
So do you think there is ability to have scrubbing feature with seeking (currentTime value change) for every frame, if video has iframe every second (every 30th frame for example)? Like in the link I shared above?

@wcandillon
Copy link
Collaborator

wcandillon commented May 28, 2024

@mrEuler would you like us to add a currentTime option where we would write the current time of the video in ms?

The scrubbing API is suggested at #2448, seems to work well on iOS and Android.

@mrEuler
Copy link
Author

mrEuler commented May 28, 2024

@wcandillon I think usage of currentTime is just common way how to control videos across different (JS) platforms. Checking the PR also.
Again many thanks!

@wcandillon
Copy link
Collaborator

just to be sure is currentTime just to check the time but not to control the scrubbing right?

@mrEuler
Copy link
Author

mrEuler commented May 28, 2024

@wcandillon I would go with both getter and setter there. So to have it working with gesture handlers under worklets with useSharedValue.

@wcandillon
Copy link
Collaborator

wcandillon commented May 28, 2024 via email

Copy link
Contributor

🎉 This issue has been resolved in version 1.3.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

@mrEuler
Copy link
Author

mrEuler commented May 28, 2024

@wcandillon Update to 1.3.1

  1. Upd: my bad here

  2. Here is the video captured on regular android phone (it's rotated in skia):
    https://drive.google.com/file/d/1x8HinlYotSnc-nqa91i3jo5JbNbbv352/view?usp=sharing

  3. Also tried code for seeking like this:

        <Pressable
            style={{ flex: 1 }}
            onPress={() => (seek.value = currentTime.value + 200)}
        >
            <Canvas style={{ flex: 1, width: width }}>
                <Fill>
                    <ImageShader
                        image={frame}
                        x={0}
                        y={0}
                        width={width}
                        height={height}
                        fit="contain"
                    />
                </Fill>
            </Canvas>
        </Pressable>

Seeking doesn't work as it should (in 90% of the time video is seeked to previous (not next) iframe: here is the video recording:

video_2024-05-28_19-40-44.mp4

Also checked, the currentTime value is reset to 0 almost every time, even though video is somewhere in the middle of playback duration

  1. I am not sure, but on recording you may see, that video isn't played at 60 fps..

@mrEuler
Copy link
Author

mrEuler commented May 28, 2024

Regarding current time here is the issue:

    if (seek.value !== null) {
      video.seek(seek.value);
      seek.value = null;
      lastTimestamp.value = -1;
      startTimestamp.value = -1; // <---- you shouldn't reset the start time
    }
    if (isPaused.value && lastTimestamp.value !== -1) {
      return;
    }
    const { timestamp } = frameInfo;

    // Initialize start timestamp
    if (startTimestamp.value === -1) {
      startTimestamp.value = timestamp;
    }

    // Calculate the current time in the video
    const currentTimestamp = timestamp - startTimestamp.value; // <-- because here after the reset the current time is 0 and it starts the "count" from the seeked moment.
    currentTime.value = currentTimestamp;

So IMHO we just need to change it to:

      const seekValue = seek.value;
      video.seek(seek.value);
      seek.value = null;
      lastTimestamp.value = -1;
      startTimestamp.value = startTimestamp.value + (currentTime.value - seekValue);

But also I would get the real currentTime value from native, because there could be a difference because of native selecting iframe (mp4 keyframe) instead of seeked time.

@wcandillon 👀

@mrEuler
Copy link
Author

mrEuler commented May 28, 2024

@wcandillon also I am checking this code:


    @DoNotStrip
    public void seek(long timestamp) {
        // Seek to the closest sync frame at or before the specified time
        extractor.seekTo(timestamp * 1000, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
        // Flush the codec to reset internal state and buffers
        if (decoder != null) {
            decoder.flush();
        }
    }

Maybe here we should use SEEK_TO_PREVIOUS_SYNC only when the timestamp is smaller value, than a current timestamp, but if larger use SEEK_TO_NEXT_SYNC.
I will try this locally.

@wcandillon wcandillon reopened this May 28, 2024
@mrEuler
Copy link
Author

mrEuler commented May 28, 2024

@wcandillon Also one more thing regarding rotated videos. When I use file picker to get the video from gallery (I use import { launchImageLibrary } from 'react-native-image-picker';) -- the dimmensions are not swapped, so for this issue I was able to make workaround (I hope app will never get rect video).

PS: Thanks for reopening this!

Copy link
Contributor

🎉 This issue has been resolved in version 1.3.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working released
Projects
None yet
2 participants