Message ID | 20210607230414.612-11-dcnieho@gmail.com |
---|---|
State | Superseded, archived |
Headers | show |
Series | avdevice (mostly dshow) enhancements | expand |
Context | Check | Description |
---|---|---|
andriy/x86_make | success | Make finished |
andriy/x86_make_fate | success | Make fate finished |
andriy/PPC64_make | success | Make finished |
andriy/PPC64_make_fate | success | Make fate finished |
Diederick Niehorster (12021-06-08): > fftools now print info about what media type(s), if any, are provided > by sink and source avdevices. Furthermore, printing is done with > av_log instead of printf as the latter doesn't handle characters in > some device names correctly (e.g. "Microphone Array (Intel® Smart > Sound Technology (Intel® SST))" is printed incorrectly). > > Signed-off-by: Diederick Niehorster <dcnieho@gmail.com> > --- > fftools/cmdutils.c | 41 +++++++++++++++++++++++++++++++---------- > 1 file changed, 31 insertions(+), 10 deletions(-) The feature looks useful. But the printing must go to stdout, not to logging, because it is meant to be readable by scripts. Regards,
On Tue, Jun 8, 2021 at 1:57 PM Nicolas George <george@nsup.org> wrote: > > The feature looks useful. But the printing must go to stdout, not to > logging, because it is meant to be readable by scripts. Done. Only problem is that now a device of mine that should be called "Microphone Array (Intel® Smart Sound Technology (Intel® SST))" is instead printed as "Intel┬« Smart Sound Technology (Intel┬« SST)". Since devices are selected by name for some avdevices (dshow), thats an issue. Googling tells me that printing UTF-8 (which is whats returned by dshow's get_device_list) with printf is complicated to say the least on Windows. It all works when logging because log.c has implemented win_console_puts(), which looks like it would be easy to make available more broadly. Do you see a solution that would allow printing the device name correctly? Thanks! Dee
Diederick C. Niehorster (12021-06-08): > Done. Only problem is that now a device of mine that should be called > "Microphone Array (Intel® Smart Sound Technology (Intel® SST))" is > instead printed as "Intel┬« Smart Sound Technology (Intel┬« SST)". > Since devices are selected by name for some avdevices (dshow), thats > an issue. > > Googling tells me that printing UTF-8 (which is whats returned by > dshow's get_device_list) with printf is complicated to say the least > on Windows. It all works when logging because log.c has implemented > win_console_puts(), which looks like it would be easy to make > available more broadly. > > Do you see a solution that would allow printing the device name correctly? What matters is not what you see in the console but what data is really written on the stream. Programs that read from the ffmpeg process and use the output to build a command line, all in a binary-clean way, should succeed. You can test with Perl (you can probably achieve the same with any language, but I know Perl, and I know it will not automagically mess things up): my $out = `ffmpeg -devices`; my $dev = $out =~ /(Microphone.*)/; print "Using \"$dev\"\n"; system "ffmpeg", "-f", "dshow", "-i", $dev; If the “Using "..."” message is mangled but the command line succeeds, then the issue is not ffmpeg's problem. Another test you can run: take a Matroska file with accents in the metadata, make sure it standard-compliant, and see what ffprobe -show_stream prints about it. Regards,
On Wed, Jun 9, 2021 at 1:15 PM Nicolas George <george@nsup.org> wrote: > > What matters is not what you see in the console but what data is really > written on the stream. Programs that read from the ffmpeg process and > use the output to build a command line, all in a binary-clean way, > should succeed. > > You can test with Perl (you can probably achieve the same with any > language, but I know Perl, and I know it will not automagically mess > things up): > > my $out = `ffmpeg -devices`; > my $dev = $out =~ /(Microphone.*)/; > print "Using \"$dev\"\n"; > system "ffmpeg", "-f", "dshow", "-i", $dev; > > If the “Using "..."” message is mangled but the command line succeeds, > then the issue is not ffmpeg's problem. I don't know perl well, but after modifying the program a bit i got it to capture the device name and call ffmpeg with it: my $out = `ffmpeg -sources dshow`; ($dev) = ( $out =~ /(Microphone.*) \[/); print "Using \"$dev\"\n"; system "ffmpeg", "-f", "dshow", "-i", "audio=\"$dev\""; The regex looks the way it does because the full output line is: "Microphone Array (Intel┬« Smart Sound Technology (Intel┬« SST)) [@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{A6F097A2-0BFA-4F4C-BF22-D4531781DA10}] (audio)" Running that perl script, i get the following output (skipping ffmpeg header): Using "Microphone Array (Intel┬« Smart Sound Technology (Intel┬« SST))" [dshow @ 000001B93364A7C0] Could not find audio only device with name [Microphone Array (Intel® Smart Sound Technology (Intel® SST))] among source devices of type audio. [dshow @ 000001B93364A7C0] Searching for audio device within video devices for Microphone Array (Intel® Smart Sound Technology (Intel® SST)) [dshow @ 000001B93364A7C0] Could not find audio only device with name [Microphone Array (Intel® Smart Sound Technology (Intel® SST))] among source devices of type video. audio=Microphone Array (Intel® Smart Sound Technology (Intel® SST)): I/O error So something isn't going quite right there. To be sure, running ffmpeg -f dshow -i audio="Microphone Array (Intel® Smart Sound Technology (Intel® SST))" directly from cmd does work. Did i make a perl error, or is there an ffmpeg problem? Thanks, Dee
diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c index 4148285971..b7018b7dab 100644 --- a/fftools/cmdutils.c +++ b/fftools/cmdutils.c @@ -2205,9 +2205,36 @@ double get_rotation(AVStream *st) } #if CONFIG_AVDEVICE +static void print_device_list(AVDeviceInfoList *device_list) +{ + int i, error_level = av_log_get_level(); + // reset log level such that info messages are displayed + // we need to use av_log instead of printf as it handles + // unicode better + av_log_set_level(AV_LOG_INFO); + // print devices + for (i = 0; i < device_list->nb_devices; i++) { + av_log(NULL, AV_LOG_INFO, "%s %s [%s]", device_list->default_device == i ? "*" : " ", + device_list->devices[i]->device_name, device_list->devices[i]->device_description); + if (device_list->devices[i]->nb_media_types > 0 && device_list->devices[i]->media_types) { + const char* media_type = av_get_media_type_string(device_list->devices[i]->media_types[0]); + av_log(NULL, AV_LOG_INFO, " (%s", media_type ? media_type : "unknown"); + for (int i = 1; i < device_list->devices[i]->nb_media_types; ++i) { + media_type = av_get_media_type_string(device_list->devices[i]->media_types[i]); + av_log(NULL, AV_LOG_INFO, ", %s", media_type ? media_type : "unknown"); + } + av_log(NULL, AV_LOG_INFO, ")"); + } else { + av_log(NULL, AV_LOG_INFO, " (none)"); + } + av_log(NULL, AV_LOG_INFO, "\n"); + } + + av_log_set_level(error_level); +} static int print_device_sources(const AVInputFormat *fmt, AVDictionary *opts) { - int ret, i; + int ret; AVDeviceInfoList *device_list = NULL; if (!fmt || !fmt->priv_class || !AV_IS_INPUT_DEVICE(fmt->priv_class->category)) @@ -2225,10 +2252,7 @@ static int print_device_sources(const AVInputFormat *fmt, AVDictionary *opts) goto fail; } - for (i = 0; i < device_list->nb_devices; i++) { - printf("%s %s [%s]\n", device_list->default_device == i ? "*" : " ", - device_list->devices[i]->device_name, device_list->devices[i]->device_description); - } + print_device_list(device_list); fail: avdevice_free_list_devices(&device_list); @@ -2237,7 +2261,7 @@ static int print_device_sources(const AVInputFormat *fmt, AVDictionary *opts) static int print_device_sinks(const AVOutputFormat *fmt, AVDictionary *opts) { - int ret, i; + int ret; AVDeviceInfoList *device_list = NULL; if (!fmt || !fmt->priv_class || !AV_IS_OUTPUT_DEVICE(fmt->priv_class->category)) @@ -2255,10 +2279,7 @@ static int print_device_sinks(const AVOutputFormat *fmt, AVDictionary *opts) goto fail; } - for (i = 0; i < device_list->nb_devices; i++) { - printf("%s %s [%s]\n", device_list->default_device == i ? "*" : " ", - device_list->devices[i]->device_name, device_list->devices[i]->device_description); - } + print_device_list(device_list); fail: avdevice_free_list_devices(&device_list);
fftools now print info about what media type(s), if any, are provided by sink and source avdevices. Furthermore, printing is done with av_log instead of printf as the latter doesn't handle characters in some device names correctly (e.g. "Microphone Array (Intel® Smart Sound Technology (Intel® SST))" is printed incorrectly). Signed-off-by: Diederick Niehorster <dcnieho@gmail.com> --- fftools/cmdutils.c | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-)