Skip to content

Commit 0c131e2

Browse files
Respect Rotation + Tests
1 parent 3f0d946 commit 0c131e2

File tree

10 files changed

+194
-16
lines changed

10 files changed

+194
-16
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.project
22
composer.lock
33
vendor
4+
.DS_Store

FfmpegVideoFile.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@ function __construct($name, $options = array()) {
2525
$this->ffmpeg = FFMpeg\FFMpeg::create($config);
2626
$this->video = $this->ffmpeg->open($name);
2727
$this->rotation = @$options["rotate_add"] ? $options["rotate_add"] : 0;
28+
$this->rotation_write = $this->rotation;
2829
$this->autorotate = @$options["autorotate"] ? $options["autorotate"] : FALSE;
2930
if (@$options["rotation"]) {
3031
try {
3132
$this->rotation += FfmpegVideoTranscoding::getRotation($name);
33+
if (!$this->autorotate)
34+
$this->rotation_write = $this->rotation;
3235
} catch (Exception $e) {
3336
}
3437
}
@@ -80,13 +83,13 @@ function saveImageBySecond($filename = NULL, $seconds = 0, $extension = "png", $
8083
$seconds = ($frameCount - 1) * $frameDuration;
8184
}
8285
$frame = $this->video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds($seconds));
83-
if (@$this->rotation && !$this->autorotate)
84-
$frame->addFilter(new RotationFrameFilter($this->rotation));
86+
if (@$this->rotation_write)
87+
$frame->addFilter(new RotationFrameFilter($this->rotation_write));
8588
$frame->save($filename);
8689
if ($safeRevertToZero && !is_file($filename)) {
8790
$frame = $this->video->frame(0);
88-
if (@$this->rotation && !$this->autorotate)
89-
$frame->addFilter(new RotationFrameFilter($this->rotation));
91+
if (@$this->rotation_write)
92+
$frame->addFilter(new RotationFrameFilter($this->rotation_write));
9093
$frame->save($filename);
9194
}
9295
return $filename;

FfmpegVideoTranscoding.php

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,15 @@ public static function transcode($source, $options) {
8686
$config["ffprobe.binaries"] = array(self::$ffprobe_binary);
8787
$ffmpeg = FFMpeg\FFMpeg::create($config);
8888
$rotation = @$options["rotate_add"] ? $options["rotate_add"] : 0;
89-
if (@$options["rotate"]) {
90-
try {
91-
$rotation += self::getRotation($source);
92-
} catch (VideoTranscodingException $e) {
93-
// Ignore it and assume rotation 0
94-
}
95-
}
9689
$autorotate = @$options["autorotate"] ? $options["autorotate"] : FALSE;
90+
$read_rotate = $rotation;
91+
try {
92+
$read_rotate += self::getRotation($source);
93+
} catch (VideoTranscodingException $e) {
94+
// Ignore it and assume rotation 0
95+
}
96+
if (!$autorotate && @$options["rotate"])
97+
$rotation = $read_rotate;
9798
$video = $ffmpeg->open($source);
9899

99100
$bitSize = 500;
@@ -124,10 +125,14 @@ public static function transcode($source, $options) {
124125
} catch (Exception $e) {
125126

126127
}
127-
128-
if (@$rotation && !@$autorotate)
128+
if ($read_rotate == 90 || $read_rotate == 270) {
129+
$temp = $originalWidth;
130+
$originalWidth = $originalHeight;
131+
$originalHeight = $temp;
132+
}
133+
if (@$rotation)
129134
$video->addFilter(new RotationFilter($rotation));
130-
if (@$originalWidth && @$originalHeight && !@$options["width"] && !@$options["height"] && ($originalWidth % 2 == 1 || $originalHeight % 2 == 1)) {
135+
if (@$originalWidth && @$originalHeight && !@$options["width"] && !@$options["height"] /*&& ($originalWidth % 2 == 1 || $originalHeight % 2 == 1)*/) {
131136
$options["width"] = $originalWidth;
132137
$options["height"] = $originalHeight;
133138
if ($options["width"] % 2 == 1)
@@ -238,10 +243,12 @@ private static function transcodeAudioVideoSeparately($source, $options) {
238243
$video = self::transcode($source, array(
239244
"format" => $options["format"],
240245
"rotate" => $options["rotate"],
246+
"autorotate" => $options["autorotate"],
241247
"rotate_add" => $options["rotate_add"]
242248
));
243249
unset($options["rotate"]);
244250
unset($options["rotate_add"]);
251+
unset($options["autorotate"]);
245252
if (!@$options["filters"])
246253
$options["filters"] = array();
247254
$options["filters"][] = new MapAndMergeFilter($audio, 0, 0);
@@ -268,10 +275,12 @@ private static function transcodeAudioVideoSeparately2($source, $options) {
268275
"noaudio" => TRUE,
269276
"format" => $options["format"],
270277
"rotate" => $options["rotate"],
278+
"autorotate" => $options["autorotate"],
271279
"rotate_add" => $options["rotate_add"]
272280
));
273281
unset($options["rotate"]);
274282
unset($options["rotate_add"]);
283+
unset($options["autorotate"]);
275284
if (!@$options["filters"])
276285
$options["filters"] = array();
277286
$options["filters"][] = new MapAndMergeFilter($audio, 0, 0);

composer.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
{
22
"name" : "ziggeo/php-ffmpeg-toolkit",
33
"description" : "A php library for running ffmpeg.",
4-
"version" : "0.0.12",
4+
"version" : "0.0.13",
55
"license" : "Apache-2.0",
66
"require" : {
7-
"php" : ">=5.3.0"
7+
"php" : ">=5.3.0",
8+
"codescale/ffmpeg-php" : "2.*",
9+
"php-ffmpeg/php-ffmpeg" : "0.11.0"
810
}
911
}

tests/assets/audio.mp3

163 KB
Binary file not shown.

tests/assets/iphone_rotated.mov

156 KB
Binary file not shown.

tests/assets/logo.png

21.3 KB
Loading

tests/assets/novideo.mp4

Whitespace-only changes.

tests/assets/video-640-360.mp4

81.4 KB
Binary file not shown.

tests/tests/FfmpegRotationTest.php

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
<?php
2+
3+
require_once(dirname(__FILE__) . "/../../vendor/autoload.php");
4+
require_once(dirname(__FILE__) . "/../../FfmpegVideoTranscoding.php");
5+
require_once(dirname(__FILE__) . "/../../FfmpegVideoFile.php");
6+
7+
8+
$SETTINGS = array(
9+
"autorotate" => FALSE
10+
);
11+
12+
$ASSETS = array(
13+
"NORMAL_VIDEO" => dirname(__FILE__) . "/../assets/video-640-360.mp4",
14+
"ROTATED_VIDEO" => dirname(__FILE__) . "/../assets/iphone_rotated.mov"
15+
);
16+
17+
$TMPFILES = array(
18+
"TMP_IMAGE" => "/tmp/test-img.png",
19+
"TMP_VIDEO" => "/tmp/test-video.mp4"
20+
);
21+
22+
23+
class FfmpegRotationTest extends PHPUnit_Framework_TestCase {
24+
25+
public function testReadRotation() {
26+
global $ASSETS, $SETTINGS;
27+
28+
$normalVideoNoRotateAdd = new FfmpegVideoFile($ASSETS["NORMAL_VIDEO"], array_merge($SETTINGS, array(
29+
"rotation" => TRUE
30+
)));
31+
$this->assertEquals($normalVideoNoRotateAdd->getWidth(), 640);
32+
$this->assertEquals($normalVideoNoRotateAdd->getHeight(), 360);
33+
$this->assertEquals($normalVideoNoRotateAdd->getRotation(), 0);
34+
35+
$normalVideoWithRotateAdd = new FfmpegVideoFile($ASSETS["NORMAL_VIDEO"], array_merge($SETTINGS, array(
36+
"rotation" => TRUE,
37+
"rotate_add" => 90
38+
)));
39+
$this->assertEquals($normalVideoWithRotateAdd->getWidth(), 360);
40+
$this->assertEquals($normalVideoWithRotateAdd->getHeight(), 640);
41+
$this->assertEquals($normalVideoWithRotateAdd->getRotation(), 90);
42+
43+
$rotatedVideoNoRotateAdd = new FfmpegVideoFile($ASSETS["ROTATED_VIDEO"], array_merge($SETTINGS, array(
44+
"rotation" => TRUE
45+
)));
46+
$this->assertEquals($rotatedVideoNoRotateAdd->getWidth(), 320);
47+
$this->assertEquals($rotatedVideoNoRotateAdd->getHeight(), 568);
48+
$this->assertEquals($rotatedVideoNoRotateAdd->getRotation(), 90);
49+
50+
$rotatedVideoWithRotateAdd = new FfmpegVideoFile($ASSETS["ROTATED_VIDEO"], array_merge($SETTINGS, array(
51+
"rotation" => TRUE,
52+
"rotate_add" => 90
53+
)));
54+
$this->assertEquals($rotatedVideoWithRotateAdd->getWidth(), 568);
55+
$this->assertEquals($rotatedVideoWithRotateAdd->getHeight(), 320);
56+
$this->assertEquals($rotatedVideoWithRotateAdd->getRotation(), 180);
57+
}
58+
59+
public function testWriteRotation() {
60+
global $ASSETS, $SETTINGS, $TMPFILES;
61+
62+
$normalVideoNoRotateAdd = new FfmpegVideoFile($ASSETS["NORMAL_VIDEO"], array_merge($SETTINGS, array(
63+
"rotation" => TRUE
64+
)));
65+
@unlink($TMPFILES["TMP_IMAGE"]);
66+
$normalVideoNoRotateAdd->saveImageByPercentage($TMPFILES["TMP_IMAGE"]);
67+
$readImg = new FfmpegVideoFile($TMPFILES["TMP_IMAGE"]);
68+
unlink($TMPFILES["TMP_IMAGE"]);
69+
$this->assertEquals($readImg->getWidth(), 640);
70+
$this->assertEquals($readImg->getHeight(), 360);
71+
$this->assertEquals($readImg->getRotation(), 0);
72+
73+
$normalVideoWithRotateAdd = new FfmpegVideoFile($ASSETS["NORMAL_VIDEO"], array_merge($SETTINGS, array(
74+
"rotation" => TRUE,
75+
"rotate_add" => 90
76+
)));
77+
@unlink($TMPFILES["TMP_IMAGE"]);
78+
$normalVideoWithRotateAdd->saveImageByPercentage($TMPFILES["TMP_IMAGE"]);
79+
$readImg = new FfmpegVideoFile($TMPFILES["TMP_IMAGE"]);
80+
unlink($TMPFILES["TMP_IMAGE"]);
81+
$this->assertEquals($readImg->getWidth(), 360);
82+
$this->assertEquals($readImg->getHeight(), 640);
83+
$this->assertEquals($readImg->getRotation(), 0);
84+
85+
$rotatedVideoNoRotateAdd = new FfmpegVideoFile($ASSETS["ROTATED_VIDEO"], array_merge($SETTINGS, array(
86+
"rotation" => TRUE
87+
)));
88+
@unlink($TMPFILES["TMP_IMAGE"]);
89+
$rotatedVideoNoRotateAdd->saveImageByPercentage($TMPFILES["TMP_IMAGE"]);
90+
$readImg = new FfmpegVideoFile($TMPFILES["TMP_IMAGE"]);
91+
unlink($TMPFILES["TMP_IMAGE"]);
92+
$this->assertEquals($readImg->getWidth(), 320);
93+
$this->assertEquals($readImg->getHeight(), 568);
94+
$this->assertEquals($readImg->getRotation(), 0);
95+
96+
$rotatedVideoWithRotateAdd = new FfmpegVideoFile($ASSETS["ROTATED_VIDEO"], array_merge($SETTINGS, array(
97+
"rotation" => TRUE,
98+
"rotate_add" => 90
99+
)));
100+
@unlink($TMPFILES["TMP_IMAGE"]);
101+
$rotatedVideoWithRotateAdd->saveImageByPercentage($TMPFILES["TMP_IMAGE"]);
102+
$readImg = new FfmpegVideoFile($TMPFILES["TMP_IMAGE"]);
103+
unlink($TMPFILES["TMP_IMAGE"]);
104+
$this->assertEquals($readImg->getWidth(), 568);
105+
$this->assertEquals($readImg->getHeight(), 320);
106+
$this->assertEquals($readImg->getRotation(), 0);
107+
}
108+
109+
public function testTranscodingRotation() {
110+
global $ASSETS, $SETTINGS, $TMPFILES;
111+
112+
@unlink($TMPFILES["TMP_VIDEO"]);
113+
FfmpegVideoTranscoding::transcodeGracefully($ASSETS["NORMAL_VIDEO"], array_merge($SETTINGS, array(
114+
"rotate" => TRUE,
115+
"resizefit" => "fit",
116+
"target" => $TMPFILES["TMP_VIDEO"],
117+
)));
118+
$readVid = new FfmpegVideoFile($TMPFILES["TMP_VIDEO"]);
119+
unlink($TMPFILES["TMP_VIDEO"]);
120+
$this->assertEquals($readVid->getWidth(), 640);
121+
$this->assertEquals($readVid->getHeight(), 360);
122+
$this->assertEquals($readVid->getRotation(), 0);
123+
124+
@unlink($TMPFILES["TMP_VIDEO"]);
125+
FfmpegVideoTranscoding::transcodeGracefully($ASSETS["NORMAL_VIDEO"], array_merge($SETTINGS, array(
126+
"rotate" => TRUE,
127+
"resizefit" => "fit",
128+
"rotate_add" => 90,
129+
"target" => $TMPFILES["TMP_VIDEO"],
130+
)));
131+
$readVid = new FfmpegVideoFile($TMPFILES["TMP_VIDEO"]);
132+
unlink($TMPFILES["TMP_VIDEO"]);
133+
$this->assertEquals($readVid->getWidth(), 360);
134+
$this->assertEquals($readVid->getHeight(), 640);
135+
$this->assertEquals($readVid->getRotation(), 0);
136+
137+
@unlink($TMPFILES["TMP_VIDEO"]);
138+
FfmpegVideoTranscoding::transcodeGracefully($ASSETS["ROTATED_VIDEO"], array_merge($SETTINGS, array(
139+
"rotate" => TRUE,
140+
"resizefit" => "fit",
141+
"target" => $TMPFILES["TMP_VIDEO"],
142+
)));
143+
$readVid = new FfmpegVideoFile($TMPFILES["TMP_VIDEO"]);
144+
unlink($TMPFILES["TMP_VIDEO"]);
145+
$this->assertEquals($readVid->getWidth(), 320);
146+
$this->assertEquals($readVid->getHeight(), 568);
147+
$this->assertEquals($readVid->getRotation(), 0);
148+
149+
@unlink($TMPFILES["TMP_VIDEO"]);
150+
FfmpegVideoTranscoding::transcodeGracefully($ASSETS["ROTATED_VIDEO"], array_merge($SETTINGS, array(
151+
"rotate" => TRUE,
152+
"resizefit" => "fit",
153+
"rotate_add" => 90,
154+
"target" => $TMPFILES["TMP_VIDEO"],
155+
)));
156+
$readVid = new FfmpegVideoFile($TMPFILES["TMP_VIDEO"]);
157+
unlink($TMPFILES["TMP_VIDEO"]);
158+
$this->assertEquals($readVid->getWidth(), 568);
159+
$this->assertEquals($readVid->getHeight(), 320);
160+
$this->assertEquals($readVid->getRotation(), 0);
161+
}
162+
163+
}

0 commit comments

Comments
 (0)