Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

[video_player] Fixed orientation and position issue for some videos metadata. #1451

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/video_player/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.10.0+5

* iOS: Fixed orientation and position issue for some videos metadata.

## 0.10.0+4

* Android: Upgrade ExoPlayer to 2.9.6.
Expand Down
20 changes: 14 additions & 6 deletions packages/video_player/ios/Classes/VideoPlayerPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -154,19 +154,27 @@ - (CGAffineTransform)fixTransform:(AVAssetTrack*)videoTrack {
// At least 2 user videos show a black screen when in portrait mode if we directly use the
// videoTrack.preferredTransform Setting tx to the height of the video instead of 0, properly
// displays the video https://github.com/flutter/flutter/issues/17606#issuecomment-413473181
if (transform.tx == 0 && transform.ty == 0) {
NSInteger rotationDegrees = (NSInteger)round(radiansToDegrees(atan2(transform.b, transform.a)));
NSLog(@"TX and TY are 0. Rotation: %ld. Natural width,height: %f, %f", (long)rotationDegrees,
videoTrack.naturalSize.width, videoTrack.naturalSize.height);
NSInteger rotationDegrees = (NSInteger)round(radiansToDegrees(atan2(transform.b, transform.a)));
// This prevents the video to be rendered out of the screen if the metadata contain a rotation but
// no translation to compensate the shift induced by the rotation.
if (rotationDegrees != 0 && transform.tx == 0 && transform.ty == 0) {
NSLog(@"Adding translation to compensate rotation. Rotation = %ld. Natural (width, height) = "
@"(%f, %f)",
(long)rotationDegrees, videoTrack.naturalSize.width, videoTrack.naturalSize.height);
NSLog(@"Uncompensated transform (a, b, c, d, tx, ty) = (%f, %f, %f, %f, %f, %f)", transform.a,
transform.b, transform.c, transform.d, transform.tx, transform.ty);
if (rotationDegrees == 90) {
NSLog(@"Setting transform tx");
transform.tx = videoTrack.naturalSize.height;
transform.ty = 0;
} else if (rotationDegrees == 180) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@quentinleguennec Thanks for your PR. I just tested your fix and unfortunately this line is not rendering videos taken at 180°. tx and ty must be 0 for videos in landscape and reverse landscape mode. Furthermore, some videos metadata include incorrect tx, ty values when in portrait mode. In https://github.com/flutter/plugins/pull/1307/files I've added a fix to properly display these videos.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be because I was using the fixed rotation metadata from this PR: #1452
On my side with both those PRs the videos display properly. (even when the video is recorded with a rotation).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tried recording your videos with the native Camera app? That's the one I used to record a video in 180° that displays a black screen with tx and ty set to non 0.

Copy link
Contributor Author

@quentinleguennec quentinleguennec Apr 15, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@recastrodiaz Good point, I didn't think about checking with the native camera app.
I just did and it is working with the current code when you record a video on your iPhone and play it with the video_player. But it is not working (black screen) if you record the video from the native camera app of an Android an play it with the video_player on an iPhone.

That's because the native iPhone camera app add the translation metadata to the video file (which can be seen with ffprobe). But Android doesn't add it (and VLC doesn't need it either, just iOS).

With the fix I added it displays the video recorded on Android properly when played on an iPhone. And it also works with a video recorded from an iPhone and played on an iPhone from the video_player.

transform.tx = videoTrack.naturalSize.width;
transform.ty = videoTrack.naturalSize.height;
} else if (rotationDegrees == 270) {
NSLog(@"Setting transform ty");
transform.tx = 0;
transform.ty = videoTrack.naturalSize.width;
}
NSLog(@"Compensated transform (a, b, c, d, tx, ty) = (%f, %f, %f, %f, %f, %f)", transform.a,
transform.b, transform.c, transform.d, transform.tx, transform.ty);
}
return transform;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/video_player/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: video_player
description: Flutter plugin for displaying inline video with other Flutter
widgets on Android and iOS.
author: Flutter Team <[email protected]>
version: 0.10.0+4
version: 0.10.0+5
homepage: https://github.com/flutter/plugins/tree/master/packages/video_player

flutter:
Expand Down