Yesterday’s PDF Animation Primer Tutorial flagged two improvements as per …
- the awkwardness of an iframe click to stop/start (PDF) animation … and …
- the way this works with only the first browsed for input PDF file
… and yes, we have achieved that today as per …
- the awkwardness of an iframe click to stop/start (PDF) animation … allow pause ⏸ (⏸) / (▶) ▶ play emoji button control
- the way this works with only the first browsed for input PDF file … by finding the second intervening place
… and along the way, for the non-Microsoft web browsers, we embed the child iframe elements (themselves containing the input PDF content, which starts out animated) within (our favourite “reveal” mechanism these days), the details/summary element combination. For multiple PDF input file executions (and single ones) we only open the last details element, so that above the fold it could be possible to see the whole scope of the execution PDF data sets.
Let’s see the new (PHP written) affected Javascript below …
<?php echo ”
function lastopen() {
var detsare=document.getElementsByTagName('details');
if (detsare.length > 0) {
detsare[eval(-1 + detsare.length)].open=true;
}
}
function loadtc(ifo, woswhich) {
//document.title+=' woslabel[0]=' + woslabel[0] + ':here with ' + woswhich;
if (woslabel.length == 0) {
setTimeout(lastopen,2000);
} else {
for (var iw=0; iw<woslabel.length; iw++) {
if (eval('' + woswhich) == eval('' + woslabel[iw].length) && woslabel[iw] != '') { wos[iw].close(); woslabel[iw]=''; if (eval(1 + iw) == eval('' + woslabel.length)) { setTimeout(lastopen,2000); } }
}
}
}
function tc(inifo) {
var ifo=document.getElementById(('' + inifo.id).replace('sup',''));
if (ifo.title == ifo.title.toLowerCase()) {
ifo.title=ifo.title.toUpperCase();
document.getElementById('sup' + ifo.id).innerHTML='▶'; // go
} else {
ifo.title=ifo.title.toLowerCase();
document.getElementById('sup' + ifo.id).innerHTML='⏸'; // stop
}
if (('' + inifo.id).indexOf('sup') == 0) {
if (('' + ifo.outerHTML).indexOf('<detail') == 0) {
ifo.open=true;
}
}
}
function pdfanimate() {
var thissrcis='', thistotalis=0, thisoneis=0, nextoneis=0, within='Within';
var ofbit='', supid='', supih='';
suffi='y';
if (document.getElementById('pdfiframe' + suffi)) {
while (document.getElementById('pdfiframe' + suffi)) {
if (('' + document.getElementById('pdfiframe' + suffi).title) == ('' + document.getElementById('pdfiframe' + suffi).title).toLowerCase()) {
thissrcis=document.getElementById('pdfiframe' + suffi).src;
thistotalis=eval(('' + thissrcis).split('=')[1].split('&')[0].split('#')[0]);
thisoneis=eval(('' + thissrcis).split('#page')[1].replace('=',''));
nextoneis=eval(1 + eval(eval('' + thisoneis) % eval('' + thistotalis)));
supid='sup' + document.getElementById('pdfiframe' + suffi).id;
if (document.getElementById('pdfiframe' + suffi).title == document.getElementById('pdfiframe' + suffi).title.toLowerCase()) {
supih='⏸';
} else {
supih='▶';
}
if (eval('' + nextoneis) == eval('' + thistotalis)) { within='End of '; } else { within='Within'; }
if (document.getElementById('pdfiframe' + suffi).getAttribute('data-pdf')) {
ofbit=' ' + document.getElementById('pdfiframe' + suffi).getAttribute('data-pdf') + ' (' + eval(1 + eval(eval('' + thisoneis) % eval('' + thistotalis))) + '/' + thistotalis + ') <sup title=Toggle onclick=parent.tc(this); id=' + supid + '>' + supih + '</sup> ';
}
if (nextoneis == 1) { // > thistotalis) {
if (document.getElementById('spanpdfiframe' + suffi)) { document.getElementById('spanpdfiframe' + suffi).innerHTML='Start of animation' + ofbit + ' ...'; }
document.getElementById('pdfiframe' + suffi).src=document.getElementById('pdfiframe' + suffi).src.split('#')[0].split('&')[0] + '&rand=' + Math.floor(Math.random() * 198765434) + '#page=1';
} else if (ofbit != '') {
thisoneis++;
if (document.getElementById('spanpdfiframe' + suffi)) { document.getElementById('spanpdfiframe' + suffi).innerHTML=within + ' animation' + ofbit + ' ...'; }
document.getElementById('pdfiframe' + suffi).src=document.getElementById('pdfiframe' + suffi).src.split('#')[0].split('&')[0] + '&rand=' + Math.floor(Math.random() * 198765434) + '#page=' + nextoneis;
} else {
thisoneis++;
if (document.getElementById('spanpdfiframe' + suffi)) { document.getElementById('spanpdfiframe' + suffi).innerHTML=''; }
document.getElementById('pdfiframe' + suffi).src=document.getElementById('pdfiframe' + suffi).src.split('#')[0].split('&')[0] + '&rand=' + Math.floor(Math.random() * 198765434) + '#page=' + nextoneis;
}
}
suffi+='y';
}
}
setTimeout(pdfanimate, 5000);
}
function animatepdf() {
setTimeout(pdfanimate, 5000);
}
“; ?>
… featuring in the changed macos_ffmpeg_convert.php PHP code.
Previous relevant PDF Animation Primer Tutorial is shown below.
The underlying web application of Image/PDF and Audio/Video Supervised Rotation Tutorial uses the great ImageMagick to convert from PDF to an Animated GIF. There’s an idea we want to see through, though, for an inhouse PDF Animation idea, starting with the URL pattern (of today’s tutorial picture) …
HTTP://localhost:8888/0____okay.pdf#page=1
… for the PDF content up the top, whereas this 7 page PDF URL …
HTTP://localhost:8888/0____okay.pdf#page=4
… gets you to the middle of the PDF document.
We weren’t sure, but we found it okay on Safari and Chrome to animate this “PDF view” via a starting URL such as …
HTTP://localhost:8888/0____okay.pdf?total=7&rand=198765453#page=1
… applied to its initial HTML state via the PHP (where $pdftotal was derived via ImageMagick‘s “identify -format %s [pdfFile]” (a 12 page PDF resulting in ‘01234567891011’ the code in function pdfpagesexec working that “total” URL argument of code below)) …
<?php echo ”
pdfpagesexec(str_replace("convert", "identify -format %s ", $verb) . " " . ourstr_replace("+"," ",$thewords) . " > /tmp/macos.idz" . $idzs . " 2>> /tmp/macos.idzerr" . $idzs . "", ourstr_replace("+"," ",$thewords));
“; ?>
… within …
<?php echo ”
$pdftotaliframe="<style> iframe { width: 100% } </style><span id=spanpdfiframe" . $idzs . ">Start of animation ...</span><br><iframe title=animation onclick=parent.tc(this); style=height:1800px id=pdfiframe" . $idzs . " src=http://" . str_replace(":443/","/",$_SERVER['SERVER_NAME'] . ":" . $_SERVER['SERVER_PORT']) . str_replace($_SERVER['DOCUMENT_ROOT'], "", $infilis) . "?total=" . $pdftotal . "#page=1></iframe>";
echo "<html><body onload=\" parent.document.getElementById('dag').innerHTML+='" . $pdftotaliframe . "<br>'; " . $parenta . " \"></body></html>";
“; ?>
… to get around cache issues (via the changing 198765453 number part of the URL) and combining with Javascript (that starts with the child iframe PDF onload event call of “parent.animatepdf();” (whereas its onclick event call is “parent.tc();”)) …
<?php echo ”
function tc(ifo) {
if (ifo.title == ifo.title.toLowerCase()) {
ifo.title=ifo.title.toUpperCase();
} else {
ifo.title=ifo.title.toLowerCase();
}
}
function pdfanimate() {
var suffi='y', thissrcis='', thistotalis=0, thisoneis=0;
if (document.getElementById('pdfiframe' + suffi)) {
while (document.getElementById('pdfiframe' + suffi)) {
if (('' + document.getElementById('pdfiframe' + suffi).title) == ('' + document.getElementById('pdfiframe' + suffi).title).toLowerCase()) {
thissrcis=document.getElementById('pdfiframe' + suffi).src;
thistotalis=eval(('' + thissrcis).split('=')[1].split('&')[0].split('#')[0]);
thisoneis=eval(('' + thissrcis).split('#page')[1].replace('=',''));
if (eval(1 + thisoneis) >= thistotalis) {
if (document.getElementById('spanpdfiframe' + suffi)) { document.getElementById('spanpdfiframe' + suffi).innerHTML='Start of animation ...'; }
document.getElementById('pdfiframe' + suffi).src=document.getElementById('pdfiframe' + suffi).src.split('#')[0] + '&rand=' + Math.floor(Math.random() * 198765434) + '#page=1';
} else {
thisoneis++;
if (document.getElementById('spanpdfiframe' + suffi)) { document.getElementById('spanpdfiframe' + suffi).innerHTML=''; }
document.getElementById('pdfiframe' + suffi).src=document.getElementById('pdfiframe' + suffi).src.split('#')[0] + '&rand=' + Math.floor(Math.random() * 198765434) + '#page=' + thisoneis;
}
}
suffi+='y';
}
}
setTimeout(pdfanimate, 3000);
}
function animatepdf() {
setTimeout(pdfanimate, 3000);
}
“; ?>
… and soon we tackle …
- the awkwardness of an iframe click to stop/start (PDF) animation … and …
- the way this works with only the first browsed for input PDF file
… and consider whether …
- a subset of functionality like this might be applicable up at the rjmprogramming.com.au domain (rather than the suggestion you download the changed PHP macos_ffmpeg_convert.php to a local web server such as MAMP (and work it with URLs such as above))
… or break it out of how it works in this web application (as a new dropdown option), the reason (for choosing this one) being that this web application is set up to both …
- accept a PDF URL
- locally browse for PDF (and where possible via Document Root map this back to a MAMP style URL (in that “Input Path” textbox))
… functionality that is a lot of trouble to replace.
Previous relevant Image/PDF and Audio/Video Supervised Rotation Tutorial is shown below.
It is the role of software to perform tasks for the user that fall into categories …
- quite difficult for the user
- inaccessible for the user
- tedious and/or too boring for the user
… in order to be useful. Of course, there are loads of other roles software has been put to, but we prefer the motivations above.
With media applications it might solve a user requirement to …
- be able to rotate the media through the four quadrants (ie. 0 (default), 90, 180 and 270 degree rotations) …
- flop (mirror vertically)
- flip (mirror horizontally)
… and today we offer a subset of all these possibilities via emoji button clicks in the header of the web application’s webpage.
Both ffmpeg (Audio/Video) and ImageMagick (Image/PDF) media helpers support these concepts, though ImageMagick appears not to support rotations and flip nor rotations and flop, and ffmpeg appears not to support flop, though your own research and development may get you more thorough results.
Both ffmpeg‘s “ffmpeg” command (for Audio/Video) and ImageMagick‘s “convert” command (for Image/PDF) media work for us via a (PHP code) pattern …
<?php
exec($verb . " " . $switchone . " " . $filename . " " . $switchtwo . " " . $outnameis . $cmdsuff . " < /tmp/macos.yes > macos_ffmpeg_convert.out 2> macos_ffmpeg_convert.err");
?>
… and it is with that PHP variable $switchtwo that has more of our attention with this work as per the table below …
Helper | Command (regarding $verb) |
Rotation (in degrees) (regarding $switchtwo for 90 180 270) |
Flop (regarding $switchtwo for 90 180 270) |
Flip (regarding $switchtwo) |
---|---|---|---|---|
ffmpeg | ffmpeg | -vf “transpose=2” −vf “transpose=2,transpose=2” -vf “transpose=1” |
-vf “transpose=0” −vf “transpose=0,transpose=0” -vf “transpose=3” |
|
Image Magick |
convert | -rotate 90 -rotate 180 -rotate 270 |
-flop | -flip |
Today’s work, then, adds onto yesterday’s Image/PDF and Audio/Video Supervised Concatenate Tutorial progress with today’s changed macos_ffmpeg_convert.php PHP code we recommend you copy to a (local web server) place suitable to work it into the use of a PHP (perhaps Apache) local web server product such as MAMP.
Previous relevant Image/PDF and Audio/Video Supervised Concatenate Tutorial is shown below.
It is a combination of …
- yesterday’s Image/PDF and Audio/Video Supervised Multiple Tutorial … with the previous …
- Concatenating Video on Command Line Tutorial
… that steers us into another couple of ideas our “+” logics could represent when we are talking about media, those being …
- concatenate audio or concatenate video … ie. string one media file onto another to achieve a final media file result
- add voiceover audio content(s) onto video(s)
… all using the talents of the brilliant Open Source ffmpeg audio and/or video media editor and manager and creator.
The conduit we use to make these media manipulations happen revolves around a Javascript Ajax and FormData object logic solution with (PHP writing Javascript) code like (where $verb points to where ffmpeg resides and infs[] array contains input media file files (with no path)) …
<?php
echo ”
var concatbit='\"concat:';
var xzhr = new XMLHttpRequest();
var xform=new FormData();
for (jut=0; jut<infs.length; jut++) {
xform.append('command' + jut, '" . $verb . " -i ' + document.getElementById('path').value + infs[jut] + ' ' + document.getElementById('path').value + infs[jut].split('.')[0] + '.ts < /tmp/macos.yes');
if (concatbit.indexOf('.ts') == -1) {
concatbit+=document.getElementById('path').value + infs[jut].split('.')[0] + '.ts';
} else {
concatbit+='|' + document.getElementById('path').value + infs[jut].split('.')[0] + '.ts';
}
}
xform.append('command' + infs.length, '" . $verb . " -i ' + concatbit + '\" -c copy ' + document.getElementById('opath').value + document.getElementById('outputname').value.split('.')[0] + '_0.ts < /tmp/macos.yes');
var isofar=eval('' + infs.length);
isofar++;
xform.append('command' + isofar, '" . $verb . " -i ' + document.getElementById('opath').value + document.getElementById('outputname').value.split('.')[0] + '_0.ts ' + document.getElementById('opath').value + document.getElementById('outputname').value + ' < /tmp/macos.yes');
for (jut=0; jut<infs.length; jut++) {
isofar++;
xform.append('command' + isofar, 'rm -f ' + infs[jut].split('.')[0] + '.ts < /tmp/macos.yes');
}
isofar++;
xform.append('command' + isofar, 'rm -f ' + document.getElementById('opath').value + document.getElementById('outputname').value.split('.')[0] + '_0.ts < /tmp/macos.yes');
isofar++;
xform.append('command' + isofar, 'open ' + document.getElementById('outputname').value);
xzhr.open('post', document.URL.split('?')[0].split('#')[0], true);
xzhr.send(xform);
“;
?>
Here is the changed macos_ffmpeg_convert.php PHP code to a place suitable to work it into the use of a PHP (perhaps Apache) local web server product such as MAMP.
Previous relevant Image/PDF and Audio/Video Supervised Multiple Tutorial is shown below.
Back at Image/PDF and Audio/Video Supervised Aesthetics Tutorial we had an assumption going that there would be a one to one correspondence of …
- input media file … to …
- output media file
… but there are quite a few scenarios where a user wants …
- several input media files … to end up as …
- one output media file
… and today we cater for …
- several input image media files … to end up as …
- one output animated GIF
- one output video
- one output PDF
… with more ideas to be tackled in days to come, based on the user involving a “+” character in their Input Media Textbox entries. Then it is likely that the user will browse for multiple local computer files as per …
<input type=file accept=".pdf,image/*,video/*,audio/*" capture multiple></input>
For today, here is the changed macos_ffmpeg_convert.php PHP code to a place suitable to work it into the use of a PHP (perhaps Apache) local web server product such as MAMP and helped out by the changed tutorial_to_animated_gif.php animated GIF creator web application, or just use the Email functionality via live run link.
Previous relevant Image/PDF and Audio/Video Supervised Aesthetics Tutorial is shown below.
That work of yesterday’s …
- Button Versus Input Type Equals Button Primer Tutorial‘s button element improved approach to working with email addresses in consort with window.localStorage “memory” (even between sessions) … combines with …
- the recent work of Image/PDF and Audio/Video Supervised Conversions Tutorial … “sprinkled with” …
- some CSS aesthetic improvements …
<style>
input[type=text] { background-color: #f0f0f0; border-radius: 5px; }
input[type=submit] { font-size: 18px; border-radius: 20px; }
button { font-size: 18px; border-radius: 20px; }
div[contenteditable=true] { font-size: 14px; border-radius: 5px; }
table { border-radius: 25px; }
</style>
… add onto various bits of inline CSS styling such as …
<body style="background: linear-gradient(to left, #ffffff 20%, #ffefba 80%); ">
… and … - some mobile platform functionality and emoji display improvements
… to give a bit of a makeover to our “Media” conversions web application, today.
Why emojis (as such) regarding “mobile” (platforms only)? Well, there is a “behind the scenes” dual purpose side to this web application on “mobile” platforms for two reasons …
- “mobile” platforms do not support our ffmpeg nor ImageMagick conversion “helpers” … and …
- called “capture” attribute of the called Local File Browsing opens the door to a user capturing their media via their smart device, and the natural urge here to share via email
… are both reasons the web application might be more apt for your “mobile” users to take a photo (we use emoji 🤳 🤳) and then email (we use emoji 📧 📧) and remind the user of this possibility, because their gaze is quite likely to fall onto these two emoji concepts on the screen. Meanwhile, in the code, we’ve tweaked things so that the conversion half of the web application’s functionality is not essential, but leave the “output” half of the web application in even for “mobile” users because a web application is what it is, for a user to work it as they will.
And what of the “command line” PHP “mode of use” for this web application? Well, we recommend you download and use the cloned convert_audiovideo_please.ksh Korn Shell script that can be a “listener” for downloaded media off those email attachments (sent to emailees). You could execute this “listener” as a macOS or Linux backup process via …
ksh convert_audiovideo_please.ksh &
And so, here is the changed macos_ffmpeg_convert.php PHP code to a place suitable to work it into the use of a PHP (perhaps Apache) local web server product such as MAMP or just use the Email functionality via live run link.
Also for the Document Conversion web application that makeover is very similar whereby the changed macos_textutil_convert.php PHP code to a place suitable to work it into the use of a PHP (perhaps Apache) local web server product such as MAMP or just use the Email functionality via Document Conversion live run link.
Previous relevant Audio and Video Supervised Conversions Primer Tutorial is shown below.
Were you here, or remember, the blog posting called MacOS Document Conversion Primer Tutorial, when we surmised …
A good thing about a “version control” or “source control” system is that you can …
- “pick up” from any version …
- “clone” to another name …
- “branch off” immediately into a new version …
… to effectively “clone” the suitable progress point from a previous project as the start to a new project.
… ? Well, yesterday’s Pandoc Document Conversion Email Tutorial felt like another such “cloning” possibility, as it felt like a “progress point” (to me and Nala). Such “cloning”, to our mind, is a bit “over the top” if there is no good reason. But we think there is. Lately, we’ve been developing “Document” conversion software. In Information Technology, under the banner of “document processing”, that work is of interest. Another area of Information Technology software concerns media … to us, that being …
- image
- audio
- video
… and it is in this “Media” field, starting out with just (the) “audio and video” (options) above, we feel we’d like to start developing “Media” conversion software, because we know of a brilliant Open Source suite of software called ffmpeg that we want to work with here. Though you might say we are “the hangers oners” in this arrangement, it is true in a lot of life’s work that getting to the smart stuff is not as easy as you’d think, and the better you can arrange it, the more efficient will the users of all this software feel.
You’ll notice with our blog posting title there being no mention of macOS or Mac OS X today. Yes, today’s “media” helper is Open Source across operating systems and we so far are not checking that you have installed ffmpeg or not. For now, it is a “suck it and see” approach. But we do not want to install ffmpeg up at our public rjmprogramming.com.au domain web server, and so we write this “Media Conversion” software with the thinking that on your local computer you may install ffmpeg and find it then useful to download the cloned macos_ffmpeg_convert.php PHP code to a place suitable to work it into the use of a PHP (perhaps Apache) local web server product such as MAMP. This PHP calls on our File API friend, a changed client_browsing.htm local file browser web application.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.