ffmpeg: 1 frame manipulation on demand - php

Hello folks & friends of SO!
We need to create a small application to take a random frame from a video, and apply some modifications to it, in real time.
This has to be done in real time, and in order to do that, we wouldn't mind to create some initial delay, before the video starts streaming. So let's assume we have a total of 6 seconds of preloading time, in order to:
1) extract a keyframe.
2) create an image with it.
3) manipulate the image.
4) replace the original keyframe with the new one.
The point (3) of the previous algorithm is already solved using GD as a PHP module. However we would need to find a solution for the rest of the procedure in order to accomplish this.
Please if anyone is available to help us with this, feel free to contact me.
Thanks in advance;
Chris C. Russo

This is a pretty complicated problem that cannot be solved by simply replacing the keyframe with a modified image. Following problems (at least) should be addressed for this to work:
Re-encoding all the frames that depend on the keyframe. Otherwise, the video would be corrupt.
File format considerations - The modified keyframe and subsequent frames are likely to have a different size after encoding (compared to the original encoded data). Storing them in the output file is not easy
Timestamp - The timestamp information for these modified frames must be preserved, else there would be audio-video sync issues in the output file.
Given these issues, my recommendation is to perform the image manipulation in the raw video frame, and encode the stream afterwards. Please let me know if I can help clarify.

Related

A random pixel on a keyframe. (ffmpeg)

Hello folks of SO!
We're trying to do some very small and simple code in PHP to generate a variation of a video, using always the same file.
The script would have to make a small pixel mark, on random or specific frame of the video file, and this would have to be streamed in real time.
Here's some pseudo code to explain my idea:
$frame = $_GET[frame];
$videofile = 'video.avi';
make_random_red_pixel_mark($videofile, $frame);
Does anyone know if this is possible using ffmpeg? As well, it is of extreamly importance for us, to execute this procedure as fast as possible.
A solution that would imply reprocessing the whole video, won't be useful for our purposes. It should be something like a closed caption, or a quick image / overlay filter that could be applied without an entire video reprocessing. As well, we can't put the overlay using Javascript nor any HTML approach, since the actual manipulation has to be on the video file itself.
The quality, and framerate of the original video, should be kept intact. Perhaps some other PHP module or software that could be execute from PHP using an exec()?
Any recommendation?
Thanks in advance!!
Chris C. Russo
More information:
1) It's possible for us to apply this procedure on any frame we want to, so we could use a "keyframe" in order to avoid the decoding and reencoding of an entire GOP.
2) As previously stated, the video stream would have to flow in real time.
This is a hard problem. The FFmpeg overlay video filter requires re-encoding.
When you change ALMOST anything in a video, you will be dealing with re-encoding of the video. This might be an expensive process depending on the video and on the how hurry you are (if you want real-time, you are in a hurry).
A possible solution for this would be something like this:
Open the INPUT video.
Create the OUTPUT video.
Loop over the packets of the INPUT video until you find the frame you want.
Reading the flags of the video packets (AVPacket structure) you can identify the Group of Pictures of this frame.
Ok, you will have to RE-ENCODE only the frames that belong to this group of pictures. Because a GOP always start with a keyframe, you will be able to do that.
After done, go on reading the packets of the INPUT and writing it to the OUTPUT (transmux).
The process of reading a packet from source and write to destination is called transmux and is very very cheap for live streaming. It's basically a plain copy of bytes. No big deal.
"The hard part here is that you will have to manage a POOL of packets until you identify the GOP where your frame is located. Why? Because you will read all packets AND STORE them in a pool (without decode the packets). When you identify it's a GOP, you will write these packets to your OUTPUT and go on to the next GOP. So you will always have the GOP in memory to be flushed (all packets together). When you identify the target frame you wanna modify. I will have to DECODE THE FRAMES from the beginning of the GOP to the end, modify the frame you want and then REENCODE this GOP! Well very hard!"
For arbitrary videos, this process above may result in a visible difference of quality of encoding in the GOP you reencoded. :-(
If you don't know how to open a video, read the packets, write the packets, etc, etc... you will have to know the basics os FFmpeg.
In order to do that, I suggest you to study this example if you don't know anything about:
Demuxing: http://ffmpeg.org/doxygen/trunk/doc_2examples_2demuxing_8c-example.html
Muxing: http://ffmpeg.org/doxygen/trunk/doc_2examples_2muxing_8c-example.html
This example will teach you how to open the video, identify the audio/video streams and loop over the packets, as well as decoding and reencoding.
Hard job. These examples are in C. You can decide make a plugin for PHP or use a PHP wrapper for FFmpeg.
OTHER SOLUTION IS: If you have flexibility of choose frame, try to reencode only keyframes. Because keyframes are complete "bitmaps". You don't need to deal with GOPs. You will decode and reencode only 1 frame.

PDF Verification in PHP

What is the best way in PHP to determine if a PDF is filled out correctly? The source PDF is a faxed form that contains handwritten data. Is an image comparison an option? If the form is filled out on a computer, I know I can use pdftotext to verify that the fields are completed or not. I just don't know how to verify handwritten data.
For hand-written data an image comparison may definitely be an option. See for example the following answer for a basic idea how to start tackling this task:
Imagemagick : “Diff” an Image
However, the job may be much more difficult when faxed images come into play. (We all know how bad a quality you can get from faxes. Also, they frequently are skewed by a small degree. And they may be slightly scaled, compared to the original. Not to forget that their resolution is 204x196dpi, which adds a bit of a distortion. And lastly -- how do you get the faxed form back into PHP? This might involve another step of scanning in the paper, which again will not necessarily add quality to the result.
Still, ImageMagick may be able to handle all this: it can -deskew images, it can reduce or completly remove -noise, and it can -distort, -scale and -repage images and much more...

given two images, determine whether one is edited from the other (and which is the original)

suppose there is an image on web without watermark. And someone downloads it and makes some edits on it like adding watermark etc etc. Is it possible to write a script in php to compare these two images. Like when I submit these two images to the script, it should be able to output the original image and manipulated image.
I read google's webmaster page which says
Google often finds multiple copies of the same image online. We use many different signals to identify the original source of the image
Blockquote
This is the main concern of my question
One more doubt is will there be any meta tags inside an image. if at all how to read them. Is it possible to edit them. Are there any information(not visual) inside an image which cannot be edited.
Anything within the image can be edited (it is, after all, just a collection of bytes), and it's definitely trivial for someone to add a watermark to an image, or simply change the contrast ever-so-slightly, to make it a very different file from the original. There are several other non-destructive changes that would make image files look completely different to a naive comparison algorithm (e.g., scaling, changing filetypes and compression, changing brightness, rotation, etc.).
Advanced image processing algorithms, however, can still often identify similarities between images that have been manipulated in ways like those above. There are many algorithms to do this, and honestly you could spend thousands of hours trying to roll an algorithm like this yourself. These sorts of algorithms are referred to as "content-based image retrieval."
You might be better off calling into engine that's already been developed to do exactly this. Here are some possibilities:
TinEye has a RESTful API that you can use, described here.
You could scrape the response from Google's Search by Image results using this technique.
You could use any of the number of suggestions within this slightly older StackOverflow post.
Good luck!
Photos taken by digital cameras usually have exif data embedded.
You can get the data with the exif_read_data function in PHP.
As for identifying similar images, here's some useful resources:
TinEye
SO Q on image similarity
The comments on Resig's article
You could submit both images to ImageEdited and see which one has been edited. Even if the exif data's missing, it tells when an image has been created with a program.

Embed code in video file

I'm sorry if the question is ambiguous, I'll try to explain.
I'm working on an existing PHP download script for videos and some parts of it are broken. There's code in there that's supposed to place a specific member code inside the video file before download, but it doesn't work. Here's the code:
//embed user's code in video file
$fpTarget = fopen($filename, "a");
fwrite($fpTarget, $member_code);
fclose($fpTarget);
$member_code is a random 6-character code.
Now, this would make sense to me if it were a text file, but since it's a video file, how could this possibly work and what is it supposed to do? If the member code is somehow added to the video, how can I see it after download it? I have no experience with video files, so any help is appreciated (a modification of the available code or new code would be equally welcome).
I'm sorry I can't give a more precise description of what the code is supposed to do, I'm trying to figure that out myself.
It may work, depending on the format/type of the video. MPG files are fairly tolerant of "noise" in a file and players would skip over your code because it doesn't look like valid video frame data.
Other formats/players may puke, because the format requires certain data be at specific offsets relative to the end of the file, which you've now shifted by 6 characters.
Your best bet is to figure see if whatever format you're serving up has provisions for metadata in its specifications. e.g. there might be support for a comment field somewhere that you can simply slap the code into.
However, if you're doing all this for 'security' or tracking unauthorized sharing of the video, then simply writing the number into a header is fairly easy to bypass. A better bet would be to watermark the video somehow so that the code is embedded in the actual video data, so that "This video belongs to member XYZ only" is displayed while playing.
You don't write to the content of the file directly, not like you would with a text file. As you've noticed, this effectively corrupts the video and you have no way of reasonably reading the information.
For audio/video files, you write to meta-data that's packaged with the file. How this is packaged and what you can do with it generally depends heavily on the container format used for the file. (Remember that container and codec are two different things. The codec is the format used to encode the audio/video, the container is the file format in which that data stream is stored.)
A library like getID3 might be a good place to start. I've never used it, but it seems to be what you're looking for. What you would essentially do is write a value to the meta-data in the container (either a pre-defined value for that container or maybe a custom key/value pair, etc.) which would be part of the file. Then, when reading the file, you can get that data. (Now, that last part depends heavily on what's reading the file. The data is there, but not every player cares about it. You'll want to match up what you're writing to with what you usually see/read from the file's internal meta-data.)

AS3 Bitmap storage

Hey,
I need some advice so I'll explain what I'm trying to accomplish, how I think I want to do it and I hope someone can tell me if this a good idea or if I'm over-thinking it.
What I want to do it take a bitmap image from an as3/Flash IDE project and save it on a database server. This is a permanent installation that has 4 flash apps running and they all link to a MySQL database.
I found this tutorial that shows me how to serialize bitmapdata and then store it on the local computer but what I'd instead like to do is store that compressed bitmap data in the database in a blob field. Is this a good idea?
If not can I send it to php to store the bitmapdata into a folder on the server and store a reference to it in the database? I can convert it to jpeg to email from the server at the moment but I need a copy that is still in bitmap format to be picked up by a 5th app and printed out.
If I do store it as a file should I then use PHP to grab the file and stream the bytes back to Flash? Is there a better way of doing it?
Any tutorials or code snippets would be greatly appreciated. If not just a push towards the right subject to read up on.
Thanks guys.
Ben
There has been great debate over the years about whether or not to store images in the DB itself. I think most of that is over and the consensus is rapidly heading to 'store it on the filesystem with a link'... you can scale that up easily, but scaling up a DB is much much harder. All of that's fine by me, because I always thought the DB guys were nuts.
For transfer over the wire, I'd suggest PNGing the image, depending on what kind of image it is (PNG is both compressed and lossless).
How to store the file will depend on how your app is structured. You can probably get by with large folders full of MD5 generated filenames to prevent collision. You probably don't want to store anything serially, as that makes it easy for somebody to come in and just take the entire set. You can also store autogenerated filenames in user id'd folders... that's up to you.
Unless high security is needed, you can just keep them all on a Web server and shoot back a URL, which makes the files readily available. If you need to keep them private, then you can stream them back with PHP. Make sure you use Etags or some other caching mechanism.
Added:
Btw, the PHP/MySql part is actually pretty easy. All in all, a seasoned pro could do it in a couple of days -- week tops.
And here's the AS3 PNG encoder, which is part of AS3CoreLib
i answered a similar question about saving bitmap into jpg file using as3 and php
Save image from Flash, send it to PHP and return a URL string to Flash

Categories