Better answer, with explanation, incorporating smart suggestions from slhck and Mulvya, stripped of non-essential parameters.
ffmpeg -i video.mp4 -i cover.jpg -acodec libmp3lame -b:a 256k -c:v copy -map 0:a:0 -map 1:v:0 output.mp3
ffmpeg audio/video manupulation tool: already selected by the OP, it is particularly fit for this job.
-i video.mp4 first input file: a video with some audio that we want to extract.
-i cover.jpg second input file, an image that we want displayed when we play the resulting audio file.
-acodec libmp3lame we want to create an .mp3 file, using the LAME encoder.
-b:a 256k this sets the bitrate for the audio track to a constant 256Kb/s. A smarter option would be to encode with a variable bitrate, specifying the quality parameter:
-q:a 0 asks for the maximum quality, while
-q:a 4 often represents a good compromise between perceived audio quality and bitrate (and hence, file size).
-c:v copy this indicates that the video stream (the .jpg image) is not to be reencoded but must be copied as it is. This is useful to avoid unnecessary processing and potential quality loss when reencoding to a lossy format. In our case, without this parameter the image would be decoded from .jpg and encoded to .png, which apparently is the native format that gets chosen by default. This would not represent a loss in quality since .png is lossles, but more often than not will cause the file size to increase, due to the fact that .jpg (being lossy) generally offers a better compression rate.
-map 0:a:0 this selects the stream to be used from the first (
0:) input file: it has to be the first (
:0) audio (
a) stream it contains.
-map 1:v:0 this selects the first (
:0) video (
v) stream from the second (
1:) input file.
output.mp3 the name of this parameter was cunningly chosen in order to already suggest that this must be the name to be given to the output audio (.mp3) file with incorporated image that we want to create.
This creates an audio (.mp3) file with a static image by putting together a video (.mp4) and a picture (.jpg) from my wedding:
ffmpeg -i video.mp4 -i cover.jpg -acodec libmp3lame -metadata title=video -b:a 256k -map_metadata 0 -map 0:1 -map 1 output.mp3
See ffmpeg documentation on selecting input streams with
-map, which is the relevant option here.
I first ran the command with simply
-map 0 -map 1 and got this info:
Stream #0:0 -> #0:0 (h264 (native) -> png (native))
Stream #0:1 -> #0:1 (aac (native) -> mp3 (libmp3lame))
Stream #1:0 -> #0:2 (mjpeg (native) -> png (native))
Thus I knew I wanted stream
1 (aac audio) from the file which has an index number of
0, i.e. the video file; therefore it had to be explicitly selected with
-map 0:1 -map 1.