Like this : ffmpeg -i input.mkv -i palette.png -lavfi paletteuse output.gif
import ffmpeg
in_filename='C:\Users\Administrator\Desktop\py\img\'
(
ffmpeg
.input(in_filename+'girl.gif')
# .filter('palettegen', stats_mode='full')
# .output(in_filename+'palettegen_full.png')
.filter(filter_name='paletteuse', dither='bayer')
.output(in_filename+'paletteuse_bayer.gif')# , vframes=1, format='image2', vcodec='mjpeg'
.run(input=b'y')
)
Cannot find a matching stream for unlabeled input pad 1 on filter Parsed_paletteuse_0
Traceback (most recent call last):
File ".../test_little.py", line 116, in
.run(input=b'y')
File "...\venv\lib\site-packages\ffmpeg_run.py", line 305, in run
raise Error('ffmpeg', out, err)
ffmpeg._run.Error: ffmpeg error (see stderr output for detail)
I think that the problem is in the keyword you pass to the .run() method. Have you tried without input=b'y'?
Instead of .run() you can try using ffmpeg.get_args([insert your input/filter/output]) to see what ffmpeg command would be used.
In fact,It's still the same mistake without input=b'y'.
input=b'y' is skipping the print step in the console, because every time the program is executed with promptsFile '...\test.gif' already exists. Overwrite ? [y/N].
You mean like this?
ffmpeg.get_args(stream_spec='ffmpeg -i input.mp4 -i palette.png -lavfi paletteuse output.gif',overwrite_output=True)
Please forgive my foolishness. I don't quite understand the use of this.Can you give me an example?
I would suggest you use .run(overwrite_output=True) instead of .run(inputb'y'). that is clearer and should have the same effect.
Ah sorry, I was not clear enough, I meant:
ffmpeg
.input(in_filename+'girl.gif')
.filter(filter_name='paletteuse', dither='bayer')
.output(in_filename+'paletteuse_bayer.gif')
.get_args()
So replace the 'run' by 'get_args'.
Hmmm,I just want to know how to let an input file output according to the palette.
It means I need to change the default palette (GIF is limited to a palette of 256 colors) to my later generated palette (generally saved into a PNG file).
Input.mp4->palette.png: palettegen
palette.png->output.gif:paletteuse
Input.mp4->output.gif: paletteuse
I need to input two filters,one is input.mp4,the other is palette.png
palette="/tmp/palette.png"
filters="fps=15,scale=320:-1:flags=lanczos"
ffmpeg -i $1 -vf "$filters,palettegen" -y $palette
ffmpeg -i $1 -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y $2
Train of thought source: ###### High quality GIF with FFmpeg
I don't know how to express -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" in ffmpeg-python.
This is my test code:
import ffmpeg
in_filename = 'C:\\Users\\Administrator\\Desktop\\emo\\pyXCX\\img\\'
(
ffmpeg
.input(in_filename+'girl.gif')
.filter(filter_name='palettegen')
.output(in_filename+'palettegen-1.png',pix_fmt='pal8')
.run(overwrite_output=True)
)
# Finish:[Parsed_palettegen_0 @ 000000000044d840] 255(+1) colors generated out of 255 colors; ratio=1.000000
print('------------------------------------------------------------------------------------')
(
ffmpeg
.input(in_filename+'girl.gif')
.concat(
ffmpeg.input(in_filename+'palettegen-1.png')
.filter(filter_name='paletteuse', dither='heckbert', new='False')
)
.output(in_filename+'output.gif')
.run(overwrite_output=True)
)
# Erorr:Palette input must contain exactly 256 pixels.
# Failed to configure input pad on Parsed_paletteuse_0
# Error reinitializing filters!
# Failed to inject frame into filter network: Invalid argument
# Error while processing the decoded data for stream #0:0
Instead of using ffmpeg.concat, use the multi-input form of ffmpeg.filter.
e.g.:
(
ffmpeg.filter(
[
ffmpeg.input(in_filename+'girl.gif'),
ffmpeg.input(in_filename+'palettegen-1.png'),
],
filter_name='paletteuse',
dither='heckbert',
new='False',
)
.output(in_filename+'output.gif')
.run(overwrite_output=True)
)
Aha,I got it.Although the output image is not the clarity I want, perhaps it is not appropriate for me to generate a palette.
Thank you.
Most helpful comment
Instead of using ffmpeg.concat, use the multi-input form of ffmpeg.filter.
e.g.: