The logic in ffmpeg_wrapper_can_decode() does not allow audio-only files to be decoded.

I'm not familiar enough with ffmpeg_wrapper to know if ffmpeg_wrapper_can_decode() should return TRUE if ffmpeg can decode at least one track in the file, or only if ffmpeg can decode all tracks present in the file.

In this patch I return true if ffmpeg can decode at least one of the video and audio codecs.

Comments

arthurf’s picture

This is a good idea, however, what I'd like to do is have the function accept audio or video as an argument- so maybe something like:

<?php
function ffmpeg_wrapper_can_deocde($path, $types = array('audio', 'video')) {
... 

 foreach ($types as $media) {
    // some files have multiple formats attached to them
   foreach(explode(',', $file_data[$media]['codec']) as $type) {

?>

what do you think?

mfb’s picture

sounds good to me

arthurf’s picture

StatusFileSize
new5.98 KB

Ok, here's a first go. There are some other changes in here from a few other patches...

mfb’s picture

You will probably have some problems with PHP notices re: undefined variables and undefined indexes.. e.g. $file_data['audio']['codec'], $file_data['video']['codec'], $can_audio_decode, $can_video_decode might not be set.

chadj’s picture

StatusFileSize
new6.02 KB

Also, I think these two lines in the patch are wrong:

   if ($types['audio'] && ! $types['video']) { return true; }  
   if ($types['video'] && ! $types['audio']) { return true; }

Since $types will have values of 'video' and 'audio', not keys. Should be

   if (in_array('audio', $types) && ! in_array('video', $types)) { return true; } 
   if (in_array('video', $types) && ! in_array('audio', $types)) { return true; }

I've attached a modified patch.

mfb’s picture

Just wanted to ping this issue as I've had to use a custom-hacked ffmpeg_wrapper.module to transcode audio files.

Audio-only transcoding is still broken at least with Media Mover since Media Mover doesn't pass in a $types argument. Also, in the 6.x-2.x branch, function can_decode_file() is missing a $types parameter so there'd be a problem even if it did.

arthurf’s picture

mfb - are you using the 1 or 2x version of ffmpeg for you audio encoding? What changes have you made to make it work correctly? I'm happy to get this fixed, I just need more direction since I haven't done any testing with audio. Also what harvest/process functions are you using with media mover that are broken?

mfb’s picture

Currently I'm still using the 1.x branch in production, but I could do some testing on the 2.x branch.

Not sure what will work for everyone (and with modules that use FFmpeg Wrapper, like Media Mover), but what I'm doing now is returning TRUE as long as there is something in the file that can be decoded:

$codecs = ffmpeg_wrapper_get_codecs('decode');
foreach (array('video', 'audio') as $media) {
  // Some files have multiple formats attached to them.
  foreach(explode(',', $file_data[$media]['codec']) as $type) {
    // Is this type in the array of items that we can decode?
    if (in_array($type, $codecs)) {
      return TRUE;
    }
  }
}

For the audio files, I am using mm_node to harvest WAV and AMR files from the upload module and mm_ffmpeg to transcode to MP3.

discipolo’s picture

got the same problem. mediamover beta7 and ffmpeg_wrapper beta2.

temporary workaround deleting line 384 "&& $can_video_decode" now audio is converted. thanx for leading me on the right track!

delykj’s picture

I modified Media Mover to fix this:

Here is the modified part of mm_ffmpeg_video function (in mm_ffmpeg.module):

function mm_ffmpeg_video(&$file, $configuration) {
  // get the file we should be operating on
  $current_file = media_mover_api_config_current_file($file);
  
  //DKJ
  $path_info = pathinfo($current_file);
  $file_ext = $path_info['extension'];
  $audiofiles = array('mp3', 'ogg', 'wav');
  if (in_array($file_ext, $audiofiles)) {    
    $types = array('audio' => 1);
  }	else{
    $types = array('video' => 1, 'audio' => 1);    
  }
  //END
  
  // first error check, make sure that we can decode  this kind of file
  //DKJ
  //if (! ffmpeg_wrapper_can_decode($current_file)) {
  if (! ffmpeg_wrapper_can_decode($current_file, $types)) {  
  //END 
discipolo’s picture

StatusFileSize
new1.42 KB

that works! here's #10 as a patch against the 6.x-1.0-beta7 version

hongpong’s picture

Issue tags: +audio, +mp3, +ffmpeg, +AIFF, +WAV

subscribing - seems to still be a problem?

arthurf’s picture

What version of ffmpeg are you using?

hongpong’s picture

Hi thanks for responding - FFmpeg version SVN-r13582
libavutil version: 49.7.0
libavcodec version: 51.58.0
libavformat version: 52.16.0
libavdevice version: 52.0.0
libavfilter version: 0.0.0

I can convert AIFFs WAVs etc from the command line but it gives in the log
FFmpeg can not decode this file type: sites/default/files/1/ajax.wav
etc. It converts video files all right but can't do wav or aiff. Tried setting a custom FFMpeg command like
-i %in_file -vn -ar 44100 -ac 2 -ab 192000 -f mp3 -acodec libmp3lame %out_file

-edit: this could be a problem from FFMpeg_converter not ffmpeg_wrapper . if so, sorry.

arthurf’s picture

can you swap the %infile for your sites/default/files/1/ajax.wav and %outfile for test.mp3 and see if it works with that command?

hongpong’s picture

Oddly even with setting that file input %infile to the specific existing file, i get errors from ffmpeg_converter like
FFmpeg can not decode this file type: sites/default/files/1/bottle.aiff
So i think maybe the calls from ffmpeg_converter are where the no-video problem is at. I think I should try using mediamover again instead. It seems like ffmpeg wrapper is not the problem, since ffmpeg_wrapper_can_decode has already been patched for this kind of situation. Hmmm :-/

-edit: this command line is fine from the server -
ffmpeg -i ajax.wav -f mp3 -acodec libmp3lame -ab 192000 -ar 44100 ajax3.mp3

hongpong’s picture

Maybe this is it. mismatch in the ffmpeg_converter function at hand.

function ffmpeg_wrapper_can_decode($path, $types = array('video', 'audio')) {
  $ffmpeg = new ffmpeg_wrapper();
  return $ffmpeg->can_decode_file($path, $types);
}

versus ffmpeg_converter.module v 1.47 2010/11/02 07:59:54 zoo33

function ffmpeg_converter_convert($input_file, $output_file, $configuration, $link = '') {
  
  // Make sure that FFmpeg can decode the input file.
  if (!ffmpeg_wrapper_can_decode($input_file)) {
    watchdog('ffmpeg_converter', 'FFmpeg can not decode this file type: %file',
             array('%file' => $input_file), WATCHDOG_WARNING, $link);
    return false;
  }
  

that If statement is missing types i think.

hongpong’s picture

I scratched out 'return false' in ffmpeg_converter and that lets it continue to process files, at least until this quirk gets cleaned up one way or another.... I think it would help to give more debugging options to show what these functions return under these tricky circumstances.

tebb’s picture

Following.

eggthing’s picture

following