0

I am working on a php code as shown below where I am converting mp4 files into mp3 using system command ffmpeg (in the case statement below).

<?php 

$mp4_files = preg_grep('~\.(mp4)$~', scandir($src_dir)); 

foreach ($mp4_files as $f)
 {

     $parts = pathinfo($f);
     switch ($parts['extension'])
     {
         case 'mp4' :
             $filePath = $src_dir . DS . $f;
             system('ffmpeg -i ' . $filePath . ' -map 0:2 -ac 1 ' . $destination_dir . DS . $parts['filename'] . '.mp3', $result);  // Through this command conversion happens. 
     }
 }

$mp3_files = preg_grep('/^([^.])/', scandir($destination_dir));

?>

After conversion, mp3 files goes into destination_dir. If new mp4 file arrives in $src_dir, the conversion usually happen on refresh of a page.

Once the conversion is complete, I am parsing everything into table as shown below:

<table>
   <tr>
      <th style="width:8%; text-align:center;">House Number</th>
      <th style="width:8%; text-align:center;">MP4 Name</th>
      <th style="width:8%; text-align:center;" >Action/Status</th>
   </tr>
   <?php
      $mp4_files = array_values($mp4_files);
      $mp3_files = array_values($mp3_files);
      foreach ($programs as $key => $program)    { 
         $file = $mp4_files[$key];     
         $file2 = $mp3_files[$key];   // file2 is in mp3 folder
      ?>
   <tr>
      <td style="width:5%; text-align:center;"><span style="border: 1px solid black; padding:5px;"><?php echo basename($file, ".mp4"); ?></span></td> <!-- House Number -->
      <td style="width:5%; text-align:center;"><span style="border: 1px solid black; padding:5px;"><?php echo basename($file); ?></span></td> <!-- MP4 Name -->             
      <td style="width:5%; text-align:center;"><button style="width:90px;" type="button" class="btn btn-outline-primary">Go</button</td>  <!-- Go Button -->
   </tr>
   <?php } ?>
</table>

Problem Statement:

I am wondering what changes I should make in the php code above that on click of a Go button, conversion of individual mp4 into mp3 happen.

On clicking of Go button, individual mp3 file (from an mp4) belonging to an individual row should go inside destination directory ($destination_dir).

enter image description here

2
  • Did you verify that your ffmpeg command works before scripting it? Because right now you're forcing it to attempt to convert the 3rd stream (-map 0:2) regardless of stream type. Are all of your inputs going to have at least 3 streams? Otherwise, use -map 0:a:0. Commented Jun 3, 2019 at 17:48
  • ffmpeg is working fine. No issues with it. We just want conversion happen on clicking of Go Button from an individual row. Commented Jun 3, 2019 at 17:49

1 Answer 1

1

The best way is to use XMLHttpRequest with better example here AJAX - Server Response

Create a javascript function like this :

<script>
  // Check if the window is loaded
  window.addEventListener('load', function () {

    // Function to call Ajax request to convert or move file
    var go = function(key, btn) {

      // Initialize request
      var xhttp = new XMLHttpRequest();

      // Execute code when the request ready state is changed and handle response.
      // Optional but recommended.
      xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
          // Do what you want here with the response here
          document.getElementById('myResponse').innerHTML = this.responseText;

          // Disable the button to not clicking again
          // see https://www.w3schools.com/jsref/prop_pushbutton_disabled.asp
          btn.disabled = true;
         }
      };

      // Handle error message here
      // Optional but recommended.
      xhttp.onerror = function(event) {
        document.getElementById('myResponse').innerHTML = 'Request error:' + event.target.status;
      };

      // Create request to the server
      // Call the page that convert .mp4 or move .mp3
      xhttp.open('POST', '/your_convert_file.php', true);

      // Pass key or name or something (secure) to retrieve the file
      // and send the request to the server
      xhttp.send('key=' + key);
    }
 )};
</script>

Add somewhere something to handle the response of the server as you want; example:

<div id="myResponse"></div>

Modify the button to call the javascript function onclick="go('<?php echo $key; ?>', this); return false;":

<button style="width:90px;" type="button" class="btn btn-outline-primary" onclick="go('<?php echo $key; ?>', this); return false;">Go</button>

Take the time to learn how works Ajax call, it's really important to communicate with the server if you don't use form

You can use JQuery but it's better without ;)

Edit

Using form, you can do this:

<form id="formId" action="your_page.php" method="post">

<!-- your table here -->

<input type="hidden" id="key" name="key" value="">
</form>

<script>
  var go = function(key) {
    document.getElementById('key').value = key;
    document.getElementById('formId').submit();
  }
</script>

Edit :

Replace $key by the House Number basename($file, ".mp4")

and the page.php or your_encoder.php as you want for an Ajax call :

// EXAMPLE FOR AJAX CALL

<?php 
// Get the unique name or key
$key = $_POST['key'];

// If key is empty, no need to go further.
if(empty($_POST['key'])) {
  echo "File name is empty !";
  exit();
}

// Can be secure by performing string sanitize
$filePath = $src_dir . DS . $key . '.mp4';

// Check if file exists
// echo a json string to parse it in javascript is better
if (file_exists($filePath)) {
    system('ffmpeg -i ' . $filePath . ' -map 0:2 -ac 1 ' . $destination_dir . DS . $parts['filename'] . '.mp3', $result);
    echo "The file $filePath has been encoded successfully.";
      . "<br />"
      . $result;
} else {
    echo "The file $filePath does not exist";
}
?>

If you use form, you have to:

  1. check if $_POST['key'] exists

  2. do the encoding if key exists

  3. send your new html table.

// EXAMPLE FOR FORM CALL

<?php
// Get the unique name or key
$key = $_POST['key'];

// If key is not empty.
if(!empty($_POST['key'])) {
  // do the encoding here like above
  // set message success | error
}

// display your html table and message here.
?>

Edit :

I know this adapted from your preview question but this code is "uncorrect", it works, no problem, but it can be optimized like this :

from...

<?php 
// Here, you list only .mp4 in the directory
// see: https://www.php.net/manual/en/function.preg-grep.php
$mp4_files = preg_grep('~\.(mp4)$~', scandir($src_dir)); 

// Here you loop only on all .mp4 
foreach ($mp4_files as $f)
 {
     $parts = pathinfo($f);

     // Here, you check if extension is .mp4
     // Useless, because it is always the case.
     // see : https://www.php.net/manual/en/control-structures.switch.php
     switch ($parts['extension'])
     {
         case 'mp4' :
             $filePath = $src_dir . DS . $f;
             system('ffmpeg -i ' . $filePath . ' -map 0:2 -ac 1 ' . $destination_dir . DS . $parts['filename'] . '.mp3', $result);  // Through this command conversion happens. 
     }
 }

$mp3_files = preg_grep('/^([^.])/', scandir($destination_dir));
?>

... to

<?php
// Here, you list only .mp4 on the directory
$mp4_files = preg_grep('~\.(mp4)$~', scandir($src_dir)); 

// Here you loop only on all .mp4 
foreach ($mp4_files as $f)
 {
     $filePath = $src_dir . DS . $f;

     // No more need to switch, preg_reg do the job before looping
     // Through this command conversion happens.
     system('ffmpeg -i ' . $filePath . ' -map 0:2 -ac 1 ' . $destination_dir . DS . pathinfo($f, 'filename') . '.mp3', $result);  
 }

$mp3_files = preg_grep('/^([^.])/', scandir($destination_dir));
?>
Sign up to request clarification or add additional context in comments.

4 Comments

Do we really need to use AJAX ? Let us imagine, we have any mp4 file here. On clicking of Go button, it should go inside $destination_dir. I think we can do without AJAX ? thoughts ?
You can do the same with form if you don't care to reload page. Form or Ajax is the same, the file moving is done by the server. In resume, you click on the button, a call to the page.php is done to the server and in page.php you do what you want.. moving, convert, rename... at the end form load the response and refresh page, ajax load response but it is invisible, you have to handle response. It's to you to make choice betwin form or ajax and betwin GET or POST. You also need to pass an identifier to retrieve file during the server process.
I am wondering that on click of a Go button, for each loop is called where conversion is happening.
To handle conversion progress or what ever that required event, you must use javascript and ajax. I don't really understand what you want to do but the process is always the same client => request => server => response => client.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.