Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
381 views
in Technique[技术] by (71.8m points)

post - How to convert mp4 files into mp3 on button click using ffmpeg/php?

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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));
?>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...