Rotate Your Movie

I have received by e-mail a rotated video in the ‘flv’ format. The video was supposed to be a vertical one, but it turned out to be horizontal, that is ROTATED. So, I wrote a little program to rotate it back using libming.
There are two things to take care of when processing the input FLV:

  • The video stream.
  • The sound stream.

Both can be taken from the FLV file.
The code is written in C++, but can be translated easily into PHP. Following is the code:

#include <iostream>
#include <mingpp.h>

using namespace std;

int main(){
  const char *flvFile ="/path/to/inputVideoFile.flv";

  // Get the video stream from the file. The input file can be in the FLV format.
  SWFVideoStream *stream = new SWFVideoStream(flvFile);

  SWFMovie mov (9);  // Create the movie object.

  // The method 'add' returns a display item.
  // Display items can be rotated, transformed, etc.
  SWFDisplayItem *di=mov.add(stream);  

  // Sound streams are taken from a file object. 
  FILE *soundFD = fopen(flvFile, "rb+");
  SWFSoundStream sound(soundFD);

  // The original dimensions of the video are 426 X 240.
  di->rotate(-90);  // Rotate the item 90 degrees clockwise
  di->move(240, 0);  // The rotation moves point (0,240) to (-240,0).


  mov.setSoundStream(&sound,0);  // Add the sound stream at the beginning
                                 // of the movie.

  // Show the frames one by one.
  int noFrames = stream->getNumFrames();
  for (int i=0; i<noFrames; i++)
      mov.nextFrame();

  mov.setDimension(240, 426); // The new dimensions.
  mov.save("/path/to/outputVideoFile.swf", 9);
  cerr<<"Fin\n";
  return 0;
}

This will create a real vertical movie. Don’t share it on YouTube or anywhere you cannot control your movie dimensions.

Advertisement

Creating Flash Sites With Ming

You probably know the SWF file format. This is not just a movie, but also can be an interactive application. SWF files can be created with the Ming PHP extension. You can get information on how to install and use the extension here. The movie format can be extended with a special scripting language, named ActionScript. Ming is not well-documented, so you can download a little API here, and maybe it will help you. There are also class for creating GUI objects, such as buttons, text fields, etc.

Let’s Discuss Some Classes

SWFMovie -The main class for movies, used for creating movies, and writing them to output streams.

Useful functions:

  • The constructor of course.
  • add – to add various objects, such as SWFAction scripts, sprites, shapes, buttons, text, etc.
  • save – to save your work to a file.
  • output – to send the output to the browser. before you send it, define the MIME type using
    header(‘Content-type: application/x-shockwave-flash’);

Notes:

  • Define the SWF version before you play it, or you will not be able to view the clip. Here‘s an user-contributed example of a way to determine the version and find more useful details. Set the version with ‘ming_useswfversion’.
  • Use scaling to avoid movies in strange sites at strange screen locations. We’ll discuss it later.
  • If you have created a movies from another movie, you must have access to the original movie from the new movie.

SWFAction – a class used for creating scripts. The scripts ca add functionality to the movie and make it interactive. It’s only function is the constructor, that takes scripts as its argument. You can use it for adding text fields – including input text fields -, communicate with other sites (using the LoadVars class for example), jumping to other frames, defining events, etc. Add it to your movie clips with the function ‘add’. Read more here.

an example of scaling with this class is:

  Stage.scaleMode='noScale';

Note: Error messages are not sent to the log, if they are not syntax errors.

SWFShape – used for creating shapes. This can be used for defining the shape of buttons (need not be rectangular). It can also be added to movie clips. With this class you can draw lines, arcs, and quadratic and cubic Bezzier curves.  You can fill your shape with colors, gradients or bitmaps. If your fill is an image, you can create an object of class SWFFill using “addFill ( SWFBitmap $bitmap [, int $flags ] ).”.  Then you can fill your shape using ‘setRightFill’ or ‘setLeftFill passing your fill as the argument.

SWFFill – This class does not have a constructor. An instance of this class is created by the function addFill of class  SWFShape . It is important to move the fill to the exact location using the function ‘moveTo’ and to scale it using ‘scaleTo”. If you want to use an image at its original dimension, you will probably have to scale it to (20,20) $fill->scaleTo(20,20) because the number of horizontal and vertical twips in a pixel is 20. In addition the fill can be rotated and/or skewed.

SWFButton – A button is a GUI element that triggers an action when clicked. You can add actions, sounds and shapes using the function addAction/setAction, addSound and addShape respectively. You better add a shape, to define the shape and location of the button. The prototype of addShape is ‘void addShape ( SWFShape $shape , int $flags )’. The flags are a combination (using bitwise or) of SWFBUTTON_UP, SWFBUTTON_OVER, SWFBUTTON_DOWN and SWFBUTTON_HIT. These flags define when the button is displayed.

An Example

This is an example of a script that plays a movie backwards:

$x = new SWFMovie();
.
.
.

$actionText = <<<'EOT'

this.createEmptyMovieClip("mc",2);

mc.loadMovie("selfie.swf", "GET");
this.gotoAndStop(mc._totalframes - 1);
this.createTextField("myText", this.getNextHighestDepth(), 0, 0, 200,220);
var tf:TextFormat = new TextFormat();
tf.color = 0x0;
tf.size = 30;
tf.font = "Arial";
myText.setTextFormat(tf);
this.addChild(myText);

this.onEnterFrame=function(){
  if (mc._currentFrame <= 1){
    mc.gotoAndPlay(mc._totalframes - 1);
  }
  mc.prevFrame();
}; 

EOT;
$act=new SWFAction($actionText);
//$x->add($text);
$x->add($act);