Problem
When present in media file metadata, the following emojis (and presumably many others as well) cause VLC to crash. This appears to be due to dbus message validation rejecting them as invalid UTF-8 sequences. However, the iconv utility accepts them. Are they invalid, or is dbus at fault here?
🔈 -> 0xf0 0x9f 0x94 0x88
🎧 -> 0xf0 0x9f 0x8e 0xa7
Details
On my system (Ubuntu 18.04), VLC crashes when attempting to play certain media files. Launching from the command line yields some information.
$ vlc problematic_file.webm
VLC media player 3.0.8 Vetinari (revision 3.0.8-0-gf350b6b5a7)
[0000557f93cb1570] main libvlc: Running vlc with the default interface. Use 'cvlc' to use vlc without interface.
dbus[3681]: arguments to dbus_message_iter_append_basic() were incorrect, assertion "_dbus_check_is_valid_utf8 (*string_p)" failed in file ../../../dbus/dbus-message.c line 2754.
This is normally a bug in some application using the D-Bus library.
D-Bus not built with -rdynamic so unable to print a backtrace
Aborted (core dumped)
Apparently I'm not the first person this has happened to. Using ffmpeg to strip out the global metadata resolved the crash.
$ ffmpeg -i problematic_file.webm -c copy -map_metadata -1 fixed.webm
Based on this, the obvious generalized solution seems to be to extract all metadata, validate it, sanitize it as necessary, and write it back. However, testing with the iconv utility indicated that the extracted (problematic) metadata was in fact valid UTF-8!
$ ffmpeg -i problematic_file.webm -f ffmetadata metadata.txt
$ iconv -f UTF-8 metadata.txt -o /dev/null; echo $?
0
Further testing indicated that the emojis identified above were the source of the problem.
Related
I wanted to edit my .m4a voice recording from Samsung Voice Recorder using ffmpeg 2.2.2, however, I got the error Invalid data found when processing input. I tried to open it through Audacity, but it returned an error claiming that the ffmpeg library is missing, which is definitely not the case. Eventually I tried to use online .m4a to .mp3 converters, but they all returned error, so I assume there may be an issue with the encoding of the original file and ffmpeg should be configured accordingly. What settings shall I use? (The original file can be played on the phone without any problem.)
ffmpeg -ss 00:00:19 -i "C:\Your\Folder\original.m4a" edited.m4a
Trying to use '-acodec libopus' in my npm project as I use in the command line like in the following format;
ffmpeg -acodec libopus -i 1.webm 1.wav
This works perfectly! But I would like to make it possible in my NPM project.
How can I set the parameters?
This is what I have , but not working. The output file is broken in a way that some of the frames of the audio file are missing. It is like there is sound and then there is not. And vice versa.
var proc = new ffmpeg({
source: file,
nolog: false
});
format = "opus"; // or could be wav as well!
proc.addOptions([
'-f ' + format,
'-acodec libopus',
'-vn'
]);
The purpose is to take audio file from the video file seamlessly.
Without the codec libopus, I get the following errors in the command prompt, so I assume I should handle the same issue in my NPM project as well.
[opus # 00000000006d4520] LBRR frames is not implemented. Update your FFmpeg version to the newest one from Git. If the problem still occurs, it means that your file has a feature which has not been implemented.
[opus # 00000000006d4520] Error decoding a SILK frame.
[opus # 00000000006d4520] Error decoding an Opus frame.
My library is up to date, I just need to use the codec libopus properly.
Any suggestions?
\node-js>ffmpeg -version
ffmpeg version N-86175-g64ea4d1 Copyright (c) 2000-2017 the FFmpeg
developers
built with gcc 6.3.0 (GCC)
Output in command line;
xtranscribe transcodeWatson: file : ./data/that/2.webm
progress 62.625273103421605%
progress 100.01224534515762%
SAVED - transcodeWatson : .mp3
out of transcode!
fileSizeInBytes : 16284033
According to the README, you can add input options to the process:
proc.addInputOption('-acodec libopus');
It matters where you place an option in ffmpeg. If you put it before -i, it applies to that particular input. If you put it before an output file name, it applies to that output.
so what happens is that if the video title has a symbol that isn't supported by your current locale then ffmpeg won't be able to get to that file properly.
Here's one example
►2 HOURS BEST MELODIC DUBSTEP MIX APRIL 2013◄ ヽ( ≧ω≦)ノ
as you may or may not be able to see, lots of symbols from unicode.
The problem is that in cmd and ffmpeg, though cmd can see
►2 HOURS BEST MELODIC DUBSTEP MIX APRIL 2013◄ ヽ( ≧ω≦)ノ
ffmpeg only sees
2 HOURS DUBSTEP_DRUMSTEP MIX AUGUST 2013 ヽ(≧ω≦)ノ
This is the exact error message (i'm using youtube-dl)
[ffmpeg] Adding metadata to 'C:\Music\ToBeDone\2014-06-01\►2 HOURS DUBSTEP_DRUMSTEP MIX AUGUST 2013◄ ヽ( ≧ω≦)ノ.mp4'
ERROR: C:\Music\ToBeDone\2014-06-01\2 HOURS DUBSTEP_DRUMSTEP MIX AUGUST 2013 ヽ(≧ω≦)ノ.mp4: No such file or directory
ERROR: WARNING: unable to obtain file audio codec with ffprobe
After some research i've determined that by changing the system locale you can change which symbols cmd can support.
However
ヽ
Used to appear as a box in a question mark in United states locale. In japanese locale it appears as it does on your screen right now.
the problem with
◄
is that even though it's not appearing as a question mark in a box (it's appearing as how it should be), ffmpeg (or cmd) can't detect it properly.
(Refer back to the error message, i'll repost it below.)
[ffmpeg] Adding metadata to 'C:\Music\ToBeDone\2014-06-01\►2 HOURS DUBSTEP_DRUMSTEP MIX AUGUST 2013◄ ヽ( ≧ω≦)ノ.mp4'
ERROR: C:\Music\ToBeDone\2014-06-01\2 HOURS DUBSTEP_DRUMSTEP MIX AUGUST 2013 ヽ(≧ω≦)ノ.mp4: No such file or directory
ERROR: WARNING: unable to obtain file audio codec with ffprobe
So as you can see, I think cmd passed on the symbol correctly to ffmpeg seeing from the adding metadata line, but when it actually does the operation ffmpeg loses
► and ◄
Could this be a bug with ffmpeg? MY workaround so far with incompatible symbols was to change the system locale, but I don't think i can do that with these two symbols...
These are the unique characters that i need to have a locale that supports
Ö
◄ ヽ( ≧ω≦)ノ
( ͡° ͜ʖ ͡°)
(_≧∇≦)
†
【
More info on the problem in general
https://github.com/rg3/youtube-dl/issues/2999
and this is what's going on (Batch Script)
#echo off
setlocal
cd C:\youtube-dl
set /p "var1=Enter URL: " %=% pause
if defined var1 set "var1=%var1:"=%"
set "var2=%date:/=-%"
set "var3=%%(title)s.%%(ext)s"
youtube-dl "%var1%" -ci -o "C:\Music\ToBeDone\%var2%\%var3%" -f best -x --no-mtime --add-metadata
youtube-dl "%var1%" --skip-download -ci -o "C:\Music\ToBeDone\%var2%\Thumbnail\%var3%" --write- thumbnail
youtube-dl "%var1%" --skip-download -ci -o "C:\Music\ToBeDone\%var2%\Description\%var3%" --write-description
The Situation:
I'm using ffmpeg (via .net) to save video files. I can get the output from ffmpeg but I dont know how can I customize the output to have better result.
My Problem:
My problem is, there is no certain difference between successful and failed operation.
last line of success:
video:1006kB audio:134kB subtitle:0 global headers:0kB muxing overhead 0.943510%
last lines from fails
c:\x\test-9-8/30/2012-9:29:56-AM.mp4: Invalid argument
rtmp://cdn.tv/cdn-live39/definst/stream01: Unknown error occurred
My Question:
Is there an option (or command line parameter) to add some sort of return code (200: success, 500: error, etc)
Thanks!
PS: I saw this topic How to tell if ffmpeg errored? but there is no number before/after last line. I think the last version doesnt have number anymore.
I know this is very old but as i came across and found no other reliable answer and after some more testing:
The suggestion with checking for return of 0 is in general a good advice - but does not help in all cases. The other idea with checking if the file exists is also good - but again - does not help in all cases.
For example when the input file is a mp3 file that has an embedded cover - then ffmpeg does (in my tests) use this image and extracts that one as an (unusable) video file.
What i do now is to have debug level output and parse it for the number of muxed packets.
ffmpeg -i "wildlife.mp4" -c:v copy -an -sn "out.mp4" -y -loglevel debug 2> wildlife.txt
With a regex i search for this text:
Output stream .+ (video): [0-9][0-9]+ packets muxed \([0-9][0-9]+ bytes\)
(this assumes that every video has more than 9 packets - could of course be optimized for really short videos).
Of course for RTMP or other settings the output may differ but i think to parse the full output stream is the only option.
You could just check the exit code returned by ffmpeg. It should return 0 on success, anything else means it failed.
You can run ffmpeg in -v error mode and have it return errors into a text file, see here: https://superuser.com/questions/100288/how-can-i-check-the-integrity-of-a-video-file-avi-mpeg-mp4 You can combine this with encoding without the null output but you will only be able to read the results from the text file.
Or you can have an additional script that will follow-up on the errors. Here is a Python example, which checks for file integrity, notice the if stdout clause. This will basically re-check encoded file if you need to see normal output first.
Solution 1:
import subprocess
import os
import sys
import re
def check_video(files):
if type(files) == str:
files = [files]
for file in files:
print(f"Checking {file}...")
command_line = f'ffmpeg -v error -i "{file}" -map 0:v -map 0:a? -vcodec copy -acodec copy -f null -'
base_name = os.path.splitext(file)[0]
extension = os.path.splitext(file)[1]
process = subprocess.Popen(command_line, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout, stderr = process.communicate()
return_code = process.returncode
pid = process.pid
print(f"Base: {base_name}")
print(f"Extension: {extension}")
print(f"RC: {return_code}")
if stdout:
allowed_errs = ["invalid as first byte of an EBML number"]
stdout_detect = stdout.decode().split("\n")
for error in allowed_errs:
if error not in stdout_detect[0] or len(stdout_detect) > 2:
print(f"Errors!")
print(os.path.splitext(file)[1])
os.rename(file, f"{file}.error")
with open(f"{file}.error.log", "w") as errfile:
if stdout:
errfile.write(stdout.decode())
if stderr:
errfile.write(stderr.decode())
else:
print("Minor problems detected.")
else:
print("File OK.")
process.wait()
if __name__ == "__main__":
files = sys.argv[1:]
# files = ["a.mkv"]
check_video(files)
Solution 2:
with subprocess.Popen(command_line,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True) as self.process:
for line in self.process.stdout:
print(line, end='')
return_code = self.process.wait()
From here, you can do whatever you like with each line, like checking for error keywords in them. I think ffmpeg has some standard of error reporting (https://ffmpeg.org/doxygen/trunk/group__lavu__error.html). With this solution, output will be displayed to you same as with directly running ffmpeg. Source: https://stackoverflow.com/a/4417735/1793606. Tested with Python 3.10
Solution 3:
Also, you can set err_detect for ffmpeg itself, that should reflect in the return code
Recently I had a task to use ffmpeg as a transcoding as well a streaming tool. The task was to convert the file from a given format to MP4 and immediately stream it, by capturing it from stdout. So far so good. The streaming works well with the native player of android tabs as well as the VLC player. The issue is with the flash player. It gives the following error:
NetStream.Play.FileStructureInvalid : Adobe Flash cannot import files that have invalid file structures.
ffmpeg flags used are
$ ffmpeg -loglevel quiet -i somefile.avi -vbsf h264_mp4toannexb -vcodec libx264 \
-acodec aac -f MP4 -movflags frag_keyframe+empty_moov -re - 2>&1
As noted in the docs for -movflags
The mov/mp4/ismv muxer supports fragmentation. Normally, a MOV/MP4 file has all the metadata about all packets stored in one location (written at the end of the file, it can be moved to the start for better playback using the qt-faststart tool). A fragmented file consists of a number of fragments, where packets and metadata about these packets are stored together. Writing a fragmented file has the advantage that the file is decodable even if the writing is interrupted (while a normal MOV/MP4 is undecodable if it is not properly finished), and it requires less memory when writing very long files (since writing normal MOV/MP4 files stores info about every single packet in memory until the file is closed). The downside is that it is less compatible with other applications.
Either switch to a flash player that can handle fragmented MP4 files, or use a different container format that supports streaming better.
Also, -re is an input-only option, so it would make more sense to specify it before the input, instead of before the output.