Closed LaurentMarquet closed 5 years ago
Hi @Laurent3170, There is currently no option to set the KiloBitrate option in the X264 interface. Have you tried to use another format, like MP3 instead of AAC?
$format->setAudioCodec("libmp3lame");
As I'm not an expert on iOS formats, I don't know any specific configuration for these devices.
Hi @Romain, thanks for your answer.
Yes I was using libmp3lame
before libfdk_aac
. I have changed to libfdk_aac
because of the link above specifying that AAC-LC is needed.
I have also tried with aac
, libvo_aacenc
and libfaac
, but the result is the same: not able to view the video on iDevices...
Do you know where I can find help ? I don't think I'm alone to have the need to have videos viewable on iDevices ;-)
I'm unsure. The best way would be for you to figure out what the ffmpeg command should be and post it here, so we can consider modifying the bundle to either create a new feature for iDevices or simply give you the ability to change the KiloBitrate for videos.
Thanks. The thing is that I don't know what my command line should look like... But I'll make investigations.
I have found https://korben.info/ffmpeg-pour-les-nuls.html (in french) that specifies the command line for iPhone ffmpeg -i source_video.avi input -acodec aac -ab 128kb -vcodec mpeg4 -b 1200kb -mbd 2 -flags +4mv+trell -aic 2 -cmp 2 -subcmp 2 -s 320x180 -title X final_video.mp4
. I have tested it but I have errors and for the time being it's still chinese for me as I have to know what means every flag...
If it talks to you... I will continue investigations but next week, as children are on holidays.
Hi @Laurent3170, Thanks for this follow-up. Feel free to paste any error here, so we can help with it.
I've made some tests. By using ffmpeg -i video-master.mov -c:v mpeg4 -r 24 -b:v 160k -c:a aac -b:a 160k -strict -2 -s 640x400 video.mp4
I should have an audio bitrate of 160kbps but I obtain 1411kbps...
I've tried to lower the -b:a
value but the result is still 1411 kbps.
Maybe it's due to the fact that I use a quite old version ffmpeg version 2.8.11-0ubuntu0.16.04.1
. I'm trying to install a newer version but its' not that easy...
Hi @Laurent3170, There is currently no option to set the KiloBitrate option in the X264 interface.
May I create a PR? I'd searched after this, but didn't found anything.
The function is present in the DefaultVideo class, but that's right, not in the H264 one. Yes a PR would be helpful. Thanks!
@Romain But it's used in the examples? And since it's just extending, why it doesn't inherit these functions? https://github.com/PHP-FFMpeg/PHP-FFMpeg#transcoding
@jens1o You're right, I answered a bit fast.
class X264 extends DefaultVideo
No need to recreate one. The example is valid.
When @Laurent3170 says:
By using
ffmpeg -i video-master.mov -c:v mpeg4 -r 24 -b:v 160k -c:a aac -b:a 160k -strict -2 -s 640x400 video.mp4
I should have an audio bitrate of 160kbps but I obtain 1411kbps...
This is not related to the bundle but to FFMPEG itself. I think you should make sure your version of FFMPEG is working properly, @Laurent3170 .
I have updated to ffmpeg version 3.2.4-1~16.04.york1
on my Ubuntu computer but the result with the ffmpeg command line is till the same... Don't know how to do better.
I have also tried
$video
->filters()
...
->setKiloBitrate(128)
...
$video
->save(new X264('libfdk_aac'), 'filenameMp4');
But I receive this error message Attempted to call an undefined method named "setKiloBitrate" of class "FFMpeg\Filters\Video\VideoFilters"
@Laurent3170, the setKiloBitrate function must be applied on a format, not on the video... ;) See the example provided by @jens1o
Ah... It works better like this! I still can't read the video on iDevices, but now I can search and "play" with data. I'll let you know. Additionally, I've found extra-spaces in the examples, I've made a PR (#318) to correct them.
Hehe, sure it's better... ;o) Thanks for the PR, I'll look at it!
So, I'm still fighting with videos...
I have a video that works on iPhone (but not made by me): https://edlo.eu/images/participatif.mp4
and the other one still not working: https://edlo.eu/6gkfwk/img/video.mp4.
They are coded both using video: H264 - MPEG-4 AVC (part 10) (avc1)
and audio: MPEG AAC Audio (mp4a) 44100 Hz
.
I don't know what to do...
If you can help, it would be greatly appreciated!
Hi @Laurent3170, I'm not an expert on iPhone encoding... I'll check if I can find some help on this...
I asked @FranckHAEGELI, who thinks that it may come from number of frame per seconds (30 when iOS only accept 23,976 , 25 or 29,97, but it's not sure that this is the problem...
Thanks for the search. Unfortunately it doesn't work. My framerate was 24. I have tested with 23,976, 25 and 29,97, but it's the same, I can't read on a iPhone. I think it's related to the sound codec, but apart with VLC, I don't know how to have all the encoding's details of a video, to check the difference between the two videos I've cited above. I've googled a while ago but it was not giving a "good" result, I'll try again later. Thanks again
I've found mediainfo which gave me information about the two video above that I have compared. Here is the result (just the meaningful differences):
Video Ok = not encoded via this library Video Nok = video encoded via this library with this code:
$framerate = new FrameRate(25);
$gop = 48;
$maximumTime = 90;
//Calculation to define $finalWidth, $finalHeight and $angle
$dimensions = new Dimension($finalWidth, $finalHeight);
$ffmpeg = FFMpeg::create(array(
'timeout' => $timeOut - 10,
'ffmpeg.threads' => 5,
));
$video = $ffmpeg->open($file);
//Resizes video
$video
->filters()
->clip(TimeCode::fromSeconds(0), TimeCode::fromSeconds($maximumTime))
->framerate($framerate, $gop)
->addMetadata(['title' => 'Title'])
->rotate($angle)
->resize($dimensions, $resizeMode, true)
->watermark(__DIR__.'/../XXX.png', array(
'position' => 'relative',
'bottom' => 50,
'right' => 50,
))
->synchronize();
//Defines format
$format = new X264();
$format
->setAudioCodec('aac')
->setKiloBitrate(1200)
->setAudioChannels(2)
->setAudioKiloBitrate(126);
//Saves video
$video->save($format, $filenameMp4);
Result Object | Video Ok | Video Nok isStreamable | Yes | No Codec profile | Main@L4 | High@L2.1 Codec settings | CABAC / 1 Ref Frames | CABAC / 6 Ref Frames
So, the main thing is that the video seems to be NOT streamable which may explain why I can't read, and the other about the Codec don't talk to me. I'll investigate about the streamable part.
This definitely looks like an encoding problem. Thanks for investigating on this and sharing your results, it's really nice to you.
I think I'd might got it.
https://trac.ffmpeg.org/wiki/Encode/H.264#Compatibility
Use simple filters to get what you want 😉
But I'm already making a pr for this.
Really thanks for your work! I have tested with the default value (main & 3.1) which should be ok for iPhone 4s but it still doesn't work :-( The format seems to be well coded as, when I do a dump, I obtain
FFMpeg\Format\Video\X264 {#1138
-bframesSupport: true
-passes: 2
#videoCodec: "libx264"
#kiloBitrate: 1200
#modulus: 16
-profile: "main"
-level: 3.1
#additionalParamaters: null
#audioCodec: "aac"
#audioKiloBitrate: 126
#audioChannels: 2
#listeners: []
}
I have also tried
$format
->setAudioCodec('aac')
->setKiloBitrate(1200)
->setAudioChannels(2)
->setAudioKiloBitrate(126)
->setProfile(Profile::HIGH)
->setLevel(4.1);
But then I obtain this error (but here it may be due to a bad copy/paste, event if I've checked)
[Symfony\Component\Debug\Exception\FatalThrowableError]
Call to a member function setLevel() on null
Oh. Thanks for searching this, there is a mistake... You'd found a bug!
Finding a bug (without knowing it) is not the main part of the problem ;-) Thanks to you!
@Laurent3170 could you paste here the complete logs so we can figure out where the error resides?
@Romain The only logs I can produce are the ones produced by the Command
I use to resize the videos, which are not useful as they only bring the error mentioned above. Can you explain me how to produce the logs you wanna see?
Ok, I misunderstood your previous message, you already pasted the logs you had.
Can you confirm that you're using your PR to do this:
$format
->setProfile(Profile::HIGH)
->setLevel(4.1);
?
Why is $format NULL? Haven't you this before?
$format = new X264();
@Romain Yes I have copied/pasted the changes from #335 on my computer and then run the script.
When I don't use setProfile
and setLevel
the video is encoded but not working on iDevices and when I use those functions the format is set as null, but There are some changes on #335 since my message above, that I haven't tested yet.
The changes were just about the test. So the result is still the same for me, not being displayed oniPhone 4s and $format = null
You must create format first then set level and profile last. Also i use baseline and level 3.0
Yes, I do
$format = new X264();
$format
->setAudioCodec('aac')
->setKiloBitrate(1200)
->setAudioChannels(2)
->setAudioKiloBitrate(126)
->setProfile(Profile::HIGH)
->setLevel(4.1);
But like this I have an error
he uses baseline and level 3.0, you're using profile high and level 4.1
Yes this was due to a bad copy/paste from the code above. But I have tried with baseline and 3.0, the $format is not null so this error has disappeared :-) the video is well encoded, but I still can't read the video https://edlo.eu/6gkfwk/img/video.mp4.
Any news ? I've tried with an iPhone 6 and still the video is not readable...
I'm afraid, but I do not have any experiences with iOS. :/
I resolved this issue. I have attached the code for you.
$format = new FFMpeg\Format\Video\X264();
if ($format instanceof VideoInterface) {
if (null !== $format->getVideoCodec()) {
$filters->add(new SimpleFilter(['-vprofile', 'baseline']));
$filters->add(new SimpleFilter(['-level', 3.0]));
}
}
@discoveryjames thanks for your answer but what is the value of $filters
?
I would also recommend using the faststart flag too, so that the whole file doesn't have to download before it starts playing.
$format = new FFMpeg\Format\Video\X264();
if ($format instanceof VideoInterface) {
if (null !== $format->getVideoCodec()) {
$filters->add(new SimpleFilter(['-vprofile', 'baseline']));
$filters->add(new SimpleFilter(['-level', 3.0]));
$filters->add(new SimpleFilter(['-movflags', '+faststart']));
}
}
Thanks for that adding (didn't know about faststart) but what about $filters
value (see my question above)?
Sorry for the confusion. I have rewritten the code anyway, I'm using the line below. This is using a php7 array, but if you're not using php7 you can just use array() instead of []
$format = new FFMpeg\Format\Video\X264();
$format->setAdditionalParameters(['-vprofile', 'baseline', '-level', 3.0, '-movflags', '+faststart']);
So, I have tried using your code but I have an encoding failed error
'/usr/bin/avconv' '-y' '-i' '/.../video-master.mov' '-metadata:s:v:0' 'rotate=0' '-async' '1' '-metadata:s:v:0' 'start_time=0' '-metadata' 'title=Title' '-ss' '0
0:00:00.00' '-t' '00:01:30.00' '-r' '29.97' '-b_strategy' '1' '-bf' '3' '-g' '48' '-threads' '4' '-vcodec' 'libx264' '-acodec' 'libfaac' '-b:v' '1000k' '-refs' '6' '-coder' '1' '-sc_threshold' '40' '-flags' '+loop' '-me_range' '16' '-subq' '7' '-i_qfactor' '0.71' '-
qcomp' '0.6' '-qdiff' '4' '-trellis' '1' '-b:a' '128k' '-vprofile' 'baseline' '-level' '3' '-movflags' '+faststart' '-vf' 'movie=/.../edlo.eu/src/AppBundle/Command/../../../web/images/stamp.png [watermark];[in]transpose=1[p0];[p0]scale=854:480 [p1];[p1]
[watermark] overlay=main_w - 50 - overlay_w:main_h - 50 - overlay_h [out]' '-pass' '1' '-passlogfile' '/tmp/ffmpeg-passes598c7977ac09554hoy/pass-598c7977ac17a' '/.../video.mp4'
So, I have also tried with
$format = new X264();
$format
->setPasses(1)
->setAudioCodec('aac')
->setKiloBitrate(1200)
->setAudioChannels(2)
->setAudioKiloBitrate(126)
->setAdditionalParameters(['-vprofile', 'baseline', '-level', 3.0, '-movflags', '+faststart'])
;
This one works and is currently in https://edlo.eu/6gkfwk/img/video.mp4, but it doesn't display on my iPhone 6... But well displayed on Firefox.
Hi @LaurentMarquet
Did you find a way to encode your videos for iOS support ? I absolutly need it.
Thanks !
No I didn't find a way...
I got it working using the following
$ffmpeg = FFMpeg\FFMpeg::create([
'ffmpeg.binaries' => '/usr/bin/ffmpeg',
'ffprobe.binaries' => '/usr/bin/ffprobe',
'timeout' => 3600,
'ffmpeg.threads' => 12,
]);
$format = new FFMpeg\Format\Video\X264();
$format->setAdditionalParameters(['-vprofile', 'baseline', '-level', 3.0, '-movflags', '+faststart']);
Thanks for your answer! I have tried (after a long-time not working on the project) and I can display it on iPhone! The settings are the same as the ones I've tried with in August 2017, but now it works. But maybe it was already the case in 2017, because (today) I saw that when I access the file directly, I can see it, but when I use a Symfony controller that return the file content + mime type it doesn't show, so maybe the problem was from here... I don't know. Thanks to all for your time, trials, etc. ! I can now close this issue :)
So it's confirmed... The problem was not only with the settings of the saved video but also with the Response sent by Symfony (in fact even with PHP directly it doesn't work).
Using Response + file_get_contents() doesn't work on iDevice, but using Symfony\Component\HttpFoundation\BinaryFileResponse
works and displays the video correctly.
We still have to use special settings to format videos for iDevices.
updated the title for more clarity
still actual :)
According to http://www.iphonefaq.org/archives/97961 (I've also found this information in other places) videos have to be encoded with H.264 video up to 720p, 30 fps and audio: AAC-LC up to 160 Kbps, 48kHz, stereo, to be viewable from iDevices.
When I encode the video using
x264
+libfdk_aac
and gets information from VLC, I have for audioMPEG AAC Audio (mp4a) / 44100 Hz / 16 bits / 1411 kbit/s
.It seems that
MPEG AAC
andAAC-LC
are the same but it looks like the KiloBitrate is too much. I've found an option to set it when saving only the audio, but can't find one when saving the video. Is there one ?Is there a specific configuration to be able to save video to be viewable from iDevices ? Thanks