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

Commit a91fa2c

Browse files
committed
Apply the correct transform for videos with different orientations
1 parent 04f64ec commit a91fa2c

File tree

4 files changed

+79
-20
lines changed

4 files changed

+79
-20
lines changed

packages/video_player/video_player_avfoundation/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 2.3.2
2+
3+
* Apply the correct transform for videos with different orientations.
4+
15
## 2.3.1
26

37
* Renames internal method channels to avoid potential confusion with the

packages/video_player/video_player_avfoundation/example/ios/RunnerTests/VideoPlayerTests.m

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
@interface FLTVideoPlayer : NSObject <FlutterStreamHandler>
1212
@property(readonly, nonatomic) AVPlayer *player;
13+
@property(readonly, nonatomic) CGAffineTransform preferredTransform;
1314
@end
1415

1516
@interface FLTVideoPlayerPlugin (Test) <FLTAVFoundationVideoPlayerApi>
@@ -121,6 +122,41 @@ - (void)testHLSControls {
121122
XCTAssertEqualWithAccuracy([videoInitialization[@"duration"] intValue], 4000, 200);
122123
}
123124

125+
- (void)testTransformFix {
126+
NSObject<FlutterPluginRegistry> *registry =
127+
(NSObject<FlutterPluginRegistry> *)[[UIApplication sharedApplication] delegate];
128+
NSObject<FlutterPluginRegistrar> *registrar = [registry registrarForPlugin:@"TestTransformFix"];
129+
FLTVideoPlayerPlugin *videoPlayerPlugin =
130+
(FLTVideoPlayerPlugin *)[[FLTVideoPlayerPlugin alloc] initWithRegistrar:registrar];
131+
132+
FlutterError *error;
133+
[videoPlayerPlugin initialize:&error];
134+
XCTAssertNil(error);
135+
136+
FLTCreateMessage *create = [FLTCreateMessage
137+
makeWithAsset:nil
138+
uri:@"https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4"
139+
packageName:nil
140+
formatHint:nil
141+
httpHeaders:@{}];
142+
FLTTextureMessage *textureMessage = [videoPlayerPlugin create:create error:&error];
143+
XCTAssertNil(error);
144+
XCTAssertNotNil(textureMessage);
145+
FLTVideoPlayer *player = videoPlayerPlugin.playersByTextureId[textureMessage.textureId];
146+
XCTAssertNotNil(player);
147+
XCTestExpectation *initializedExpectation = [self expectationWithDescription:@"initialized"];
148+
[player onListenWithArguments:nil
149+
eventSink:^(NSDictionary<NSString *, id> *event) {
150+
if ([event[@"event"] isEqualToString:@"initialized"]) {
151+
[initializedExpectation fulfill];
152+
}
153+
}];
154+
[self waitForExpectationsWithTimeout:30.0 handler:nil];
155+
CGAffineTransform transform = player.preferredTransform;
156+
XCTAssertEqual(transform.tx, 0.0f);
157+
XCTAssertEqual(transform.ty, 0.0f);
158+
}
159+
124160
- (NSDictionary<NSString *, id> *)testPlugin:(FLTVideoPlayerPlugin *)videoPlayerPlugin
125161
uri:(NSString *)uri {
126162
FlutterError *error;

packages/video_player/video_player_avfoundation/ios/Classes/FLTVideoPlayerPlugin.m

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -187,27 +187,46 @@ - (instancetype)initWithURL:(NSURL *)url
187187
return [self initWithPlayerItem:item frameUpdater:frameUpdater];
188188
}
189189

190+
// Fix the transform for the given track.
191+
// Each fix case corresponding to `UIImage.Orientation`,
192+
// with 8 cases in total.
190193
- (CGAffineTransform)fixTransform:(AVAssetTrack *)videoTrack {
191-
CGAffineTransform transform = videoTrack.preferredTransform;
192-
// TODO(@recastrodiaz): why do we need to do this? Why is the preferredTransform incorrect?
193-
// At least 2 user videos show a black screen when in portrait mode if we directly use the
194-
// videoTrack.preferredTransform Setting tx to the height of the video instead of 0, properly
195-
// displays the video https://github.com/flutter/flutter/issues/17606#issuecomment-413473181
196-
if (transform.tx == 0 && transform.ty == 0) {
197-
NSInteger rotationDegrees = (NSInteger)round(radiansToDegrees(atan2(transform.b, transform.a)));
198-
NSLog(@"TX and TY are 0. Rotation: %ld. Natural width,height: %f, %f", (long)rotationDegrees,
199-
videoTrack.naturalSize.width, videoTrack.naturalSize.height);
200-
if (rotationDegrees == 90) {
201-
NSLog(@"Setting transform tx");
202-
transform.tx = videoTrack.naturalSize.height;
203-
transform.ty = 0;
204-
} else if (rotationDegrees == 270) {
205-
NSLog(@"Setting transform ty");
206-
transform.tx = 0;
207-
transform.ty = videoTrack.naturalSize.width;
208-
}
194+
CGAffineTransform t = videoTrack.preferredTransform;
195+
CGSize size = videoTrack.naturalSize;
196+
if (t.a == 1 && t.b == 0 && t.c == 0 && t.d == 1) {
197+
// Orientation.up
198+
t.tx = 0;
199+
t.ty = 0;
200+
} else if (t.a == -1 && t.b == 0 && t.c == 0 && t.d == 1) {
201+
// Orientation.upMirrored
202+
t.tx = size.width;
203+
t.ty = 0;
204+
} else if (t.a == -1 && t.b == 0 && t.c == 0 && t.d == -1) {
205+
// Orientation.down
206+
t.tx = size.width;
207+
t.ty = size.height;
208+
} else if (t.a == 1 && t.b == 0 && t.c == 0 && t.d == -1) {
209+
// Orientation.downMirrored
210+
t.tx = 0;
211+
t.ty = size.height;
212+
} else if (t.a == 0 && t.b == -1 && t.c == 1 && t.d == 0) {
213+
// Orientation.left
214+
t.tx = 0;
215+
t.ty = size.width;
216+
} else if (t.a == 0 && t.b == -1 && t.c == -1 && t.d == 0) {
217+
// Orientation.leftMirrored
218+
t.tx = size.height;
219+
t.ty = size.width;
220+
} else if (t.a == 0 && t.b == 1 && t.c == -1 && t.d == 0) {
221+
// Orientation.right
222+
t.tx = size.height;
223+
t.ty = 0;
224+
} else if (t.a == 0 && t.b == 1 && t.c == 1 && t.d == 0) {
225+
// Orientation.rightMirrored
226+
t.tx = 0;
227+
t.ty = 0;
209228
}
210-
return transform;
229+
return t;
211230
}
212231

213232
- (instancetype)initWithPlayerItem:(AVPlayerItem *)item

packages/video_player/video_player_avfoundation/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: video_player_avfoundation
22
description: iOS implementation of the video_player plugin.
33
repository: https://github.com/flutter/plugins/tree/master/packages/video_player/video_player_avfoundation
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+video_player%22
5-
version: 2.3.1
5+
version: 2.3.2
66

77
environment:
88
sdk: ">=2.14.0 <3.0.0"

0 commit comments

Comments
 (0)