Save audio file in chunk from original file - php

I actually want a demo version for audio file. I uploaded audio file in mp3 format on server with php script. I want that it run for 30 seconds in demo mode and for register user it play whole file.
There is a solution using ffmpeg library while uploading split file in frames and save one for demo and one for original. But I need some different solution because ffmpeg not available on shared server.
Please help me to solve this problem.

You can't cut an MP3 (reliably) on frames alone. There is something called a bit reservoir, where basically frames can rely on other frames. Most frames will be using this feature. If you cut on the frame, you will undoubtedly end up with a corrupt file, and have a few artifacts in your clip.
To do what you are asking, you have two options:
Parse the MP3 data and cut only on frames not using the bit reservoir
Write an encoder that can cut on any frame and fix the bit reservoir so that prior and latter frames are not needed.
Neither of these are good options. Call your web host, get FFMPEG installed. If they won't put it on there for you, get a new hosting provider. Don't waste your time with anything else.

Related

Create a PDF file on the fly and stream it while it is not yet finished?

We want to merge a lot of PDF files into one big file and send it to the client. However, the resources on our production server are very restricted, so merging all files in memory first and then sending the finished PDF file results in our script being killed because it exhausts its available memory.
The only solution (besides getting a better server, obviously) would be starting to stream the PDF file before it is fully created to bypass the memory limit.
However I wonder if that is even possible. Can PDF files be streamed before they're fully created? Or doesn't the PDF file format allow streaming unfinished files because some headers or whatever have to be set after the full contents are certain?
If it is possible, which PDF library supports creating a file as a stream? Most libraries that I know of (like TCPDF) seem to create the full file in memory and then in the end output this finished result somewhere (i. e. via the $tcpdf->Output() method).
The PDF file format is entirely able to be streamed. There's certainly nothing that'll prevent it anyway.
As an example, we recently had a customer that required reading a single page over a HTTP connection to a remote PDF, without downloading or reading the whole PDF. We're able to do this by making many small HTTP requests for specific content within the PDF. We use the trailer at the end of the PDF and the cross reference table to find the required content without having to parse the whole PDF.
If I understand your problem, it looks like your current library you're using loads each PDF in memory before creating or streaming out the merged document.
If we look at this problem a different way, the better solution would be for the PDF library to only take references to the PDFs to be merged, then when the merged PDF is being created or streamed, pull in the content and resources from the PDFs to be merged, as-and-when required.
I'm not sure how many PHP libraries there are that can do this as I'm not too up-to-date with PHP, but I know there are probably a few C/C++ libraries that may be able to do this. I understand PHP can use extensions to call these libraries. Only downside is that they'll likely have commercial licenses.
Disclaimer: I work for the Mako SDK R&D group, hence why I know for sure there are some libraries which will do this. :)

extract images from PDF with PHP

The thing is that the client wants to upload a pdf with images as a way of batch processing multiple images at once.
I already looked around and out of the box PHP can't read PDF's.
What are my alternatives?
I already know the host has not installed imageMagick or any pdf library and the exec function is disabled. That's basicly leaving me with nothing to work with, I guess?
Does anyone know if there is an online service that can do this, with an api of sorts?
thanks in adv
AFAIK, there is no PHP module to do it. There is a command line tool, pdfimages (part of xpdf). For reference, here's how that works:
pdfimages -j source.pdf image
Which will extract all images from source.pdf as image-000.jpg, image-001.jpg, etc. Note the output format is always Jpeg.
Possible Options
Being a command line tool, you need exec (or system, passthru, any of the command executing functions built into PHP). As your environment doesn't have that, I see four options:
Beg that exec be turned on for you (your hosting provider can limit what you can exec to a single command)
Change the design -- how about a ZIP upload?
Roll your own, using the source code of pdfimages as a model
Let pdfimages do the heavy lifting, by running it on a remote host you do control
Regarding #3, rolling your own, I don't think rolling your own, to solve a very narrow definition of requirements, would be too difficult. I seem to recall that the image boundaries in PDF are well defined: just read in the file to a boundary, cut to the end of the boundary, base64_decode, and write to a file -- repeat. However, that may be too much...
If rolling your own is too complicated, then option #4 is kind of like what Joel Spolsky describes for working with complicated Excel objects (see the numbered list under the bold heading "Let Office do the heavy work for you").
Find a cheap hosting environment (eg Amazon EC2) that let's you exec and curl
Install pdfimages
Write a PHP script that takes a URL to a PDF, curl opens that PDF, writes it to disk, passes it to pdfimages, then returns the URL to the resulting images.
An example exchange could look like this:
GET http://www.cheaphost.com/pdfimages.php?extract=http://www.limitedhost.com/path/to/uploaded.pdf
Content-type: text/html
<html>
<body>
<ul>
<li>http://www.cheaphost.com/pdfimages.php?retrieve=ab9895v/image-000.jpg</li>
<li>http://www.cheaphost.com/pdfimages.php?retrieve=ab9895v/image-001.jpg</li>
</ul>
</body>
</html>
So your single pdfimages.php script (running on the host with the exec functionality) can both extract images, and give you access to the extracted images. When extracting, it reads a PDF you tell it, runs pdfimages on it, and gives you back a list of URL to call to retrieve the extracted images. When retrieving, it just gives you back a straight image.
You would need to deal with cleanup, perhaps the thing to do would be to delete the image after retrieval. You would also need to handle security -- don't know what's in these images, but the content might need to be wrapped in SSL and other precautions taken.
You can use pdfimages and install it this way:
apt install poppler-utils
Then use it this way to get all the images as PNG files:
pdfimages -j mypdf.pdf image -png
Images will be placed in the same folder under image-000.png, image-001.png, etc.
There are many options available, including some to change the output format, more information here.
I hope this helps!

Video file splitting on the fly

I'm downloading videos from a 3rd party server (mostly flv, mp4) using php script, after download I'm cutting video at 1:30 mins - now it's ready to be played. Is it possible to download only part (1-2 mins) of the video instead of whole file and still being able to play it (the way it's now it's simply wasting bandwidth, CPU...)?
This is very hard to do, as it requires your script to understand MP4 or FLV. However, this may help you (please note that it still requires ffmpeg, FLVTools2 and Mencode to be installed).
Cutting a flv or mp4 involves some index updating, looking for a possible cutting point etc. Building that in php seems overkill. Look into some Tools that can download and cut in one step and call those from your php. FFMpeg and MPlayer may be able to do that.

How to quickly zip large files in PHP

I wrote a PHP script to dynamically pack files selected by the client into zip file and force a download. It works well except that when the number of files is huge (like over 50000), it takes a very long time for the download dialog box to appear on the client side.
I thought about improving this using cache (these files are not changed very often), but because the selection of the files are totally decided by the user, and there are tens of thousands of combinations on the selection, it is very hard to cache combinations. I also thought about generating zip archives for individual files first, and then combining the zip files on-the-fly. But I did't find a way to concatenate zip files in PHP. Another way I can think of is sending (i.e., reading) the zip file at the same time as generating it. I also don't know if this is supported.
If someone could help me on this, I would really appreciate your help.
To extened Mike Sherov's answer, try using a combination of Tar and Gzip/Zip. Individually pre-compress all the files using Gzip/Zip, Then when the client makes their selection, you simply Tar those files together. That way you still get the benefit of compression and the simplicity of downloading one file, but none of the overheads and delays associated with compressing large files in real time.
While not a silver bullet, you can try tar'ing the files instead. The resulting file is larger, but compression time is much shorter. See here for more info: http://birdhouse.org/blog/2010/03/08/zip-vs-tar-gzip/
Check out mod_zip for Nginx:
https://github.com/evanmiller/mod_zip
It streams a ZIP file to the client dynamically and can include very large (2GB+) files while using very little RAM.

PHP Extract audio from video

I need a way to extract the audio from some video (in PHP). I have the video streaming in from YouTube, so I would really like it if it were on the fly streaming, not I have to save it to a temp directory and process it there (though that is acceptable.) Thanks, Isaac Waller
Edit: to be more specific, I have a MP4 and I want it to be a MP3.
You're going to want to use something like ffmpeg and call it using php's exec command. If you look around in the docs, I'm sure you can figure out what flag to use to only get the audio.
I've used this app before on a project for live transcoding of video, works like a charm. Just make sure your server has it correctly installed.
Mplayer should do this for you, and there are libraries and codecs that you can call (PHP supports C libraries) which will strip the video from the AV stream on the fly.
Given that you're targeting youttube your job is a bit easier because they use a very small subset of file encodings.
If you take the time to learn the format, you can very easily remove the video stream on the fly and return only the audio stream.
If you give a little more information, such as what you're encoding it to, or where it's going to end up we may be able to help more specifically.
-Adam

Categories