ffmpeg -formats ffmpeg -sample_fmts ffmpeg -i ../english14.mp3 -ar 44100 -ac 2 -sample_fmt s16 -f wav english14.wav ffmpeg -i ../english14.mp3 -ar 44100 -ac 2 -sample_fmt s16 -f s16le english14.pcm 其中针对PCM个数的数据aplay正确的播放格式为: aplay -r 48000 -c 2 english14.pcm 下面都是错误的格式,声音不能正常识别 aplay -c 2 english14.pcm aplay -r 48000 english14.pcm aplay english14.pcm /home/suiyuan626/share/alsa-utils-1.2.6/aplay/aplay -v -t raw -f S16_LE -r 48000 -c 2 english14.pcm 此处的aplay来自alsa-utils-1.2.6中源码编译 suiyuan626@ubuntu:~/share/ffmpeg/ffmpeg/doc/examples/data$ /home/suiyuan626/share/alsa-utils-1.2.6/aplay/aplay -v -f S16_LE -r 48000 -c 2 english14.pcm Playing raw data 'english14.pcm' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo ALSA <-> PulseAudio PCM I/O Plugin Its setup is: stream : PLAYBACK access : RW_INTERLEAVED format : S16_LE subformat : STD channels : 2 rate : 48000 exact rate : 48000 (48000/1) msbits : 16 buffer_size : 24000 period_size : 6000 period_time : tstamp_mode : NONE tstamp_type : GETTIMEOFDAY period_step : 1 avail_min : 6000 period_event : 0 start_threshold : 24000 stop_threshold : 24000 silence_threshold: 0 silence_size : 0 boundary : ^CAborted by signal Interrupt... 上面的命令中使用 -f -r -c 参数 参数 -f ,其主要配置的是 根据用户给定的参数格式找出PCM.h中定义的采样个事,采样率和通道数 case 'f': force_sample_format = 1; if (strcasecmp(optarg, "cd") == 0 || strcasecmp(optarg, "cdr") == 0) { if (strcasecmp(optarg, "cdr") == 0) rhwparams.format = SND_PCM_FORMAT_S16_BE; else rhwparams.format = file_type == FORMAT_AU ? SND_PCM_FORMAT_S16_BE : SND_PCM_FORMAT_S16_LE; rhwparams.rate = 44100; rhwparams.channels = 2; } else if (strcasecmp(optarg, "dat") == 0) { rhwparams.format = file_type == FORMAT_AU ? SND_PCM_FORMAT_S16_BE : SND_PCM_FORMAT_S16_LE; rhwparams.rate = 48000; rhwparams.channels = 2; } else { rhwparams.format = snd_pcm_format_value(optarg); if (rhwparams.format == SND_PCM_FORMAT_UNKNOWN) { error(_("wrong extended format '%s'"), optarg); prg_exit(EXIT_FAILURE); } } break; case 'r': tmp = parse_long(optarg, &err); if (err < 0) { error(_("invalid rate argument '%s'"), optarg); return 1; } if (tmp < 1000) tmp *= 1000; rhwparams.rate = tmp; if (tmp < 2000 || tmp > ) { error(_("bad speed value %i"), tmp); return 1; } break case 'c': rhwparams.channels = parse_long(optarg, &err); if (err < 0) { error(_("invalid channels argument '%s'"), optarg); return 1; } if (rhwparams.channels < 1 || rhwparams.channels > 256) { error(_("value %i for channels is invalid"), rhwparams.channels); return 1; } break; 使用aplay要么record,要么播放文件,从stream的定义中可以知道 / PCM stream (direction) */ typedef enum _snd_pcm_stream { / Playback stream */ SND_PCM_STREAM_PLAYBACK = 0, / Capture stream */ SND_PCM_STREAM_CAPTURE, SND_PCM_STREAM_LAST = SND_PCM_STREAM_CAPTURE } snd_pcm_stream_t; static void header(int rtype, char *name) { if (!quiet_mode) { if (! name) name = (stream == SND_PCM_STREAM_PLAYBACK) ? "stdout" : "stdin"; fprintf(stderr, "%s %s '%s' : ", (stream == SND_PCM_STREAM_PLAYBACK) ? _("Playing") : _("Recording"), gettext(fmt_rec_table[rtype].what), name); fprintf(stderr, "%s, ", snd_pcm_format_description(hwparams.format)); fprintf(stderr, _("Rate %d Hz, "), hwparams.rate); if (hwparams.channels == 1) fprintf(stderr, _("Mono")); else if (hwparams.channels == 2) fprintf(stderr, _("Stereo")); else fprintf(stderr, _("Channels %i"), hwparams.channels); fprintf(stderr, "\n"); } } 有没有设置-I参数,故执行playback()函数进行播放,同时我们可以添加参数 -t 来执行播放文件类型 case 't': if (strcasecmp(optarg, "raw") == 0) file_type = FORMAT_RAW; else if (strcasecmp(optarg, "voc") == 0) file_type = FORMAT_VOC; else if (strcasecmp(optarg, "wav") == 0) file_type = FORMAT_WAVE; else if (strcasecmp(optarg, "au") == 0 || strcasecmp(optarg, "sparc") == 0) file_type = FORMAT_AU; else { error(_("unrecognized file format %s"), optarg); return 1; } break; static void playback(char *name) { int loaded = 0; pbrec_count = LLONG_MAX; fdcount = 0; if (!name || !strcmp(name, "-")) { fd = fileno(stdin); name = "stdin"; } else { init_stdin(); if ((fd = open(name, O_RDONLY, 0)) == -1) { perror(name); prg_exit(EXIT_FAILURE); } } printf("name:%s,file_type:%d\n",name,file_type); switch(file_type) { case FORMAT_AU: playback_au(name, &loaded); break; case FORMAT_VOC: playback_voc(name, &loaded); break; case FORMAT_WAVE: playback_wave(name, &loaded); break; case FORMAT_RAW: playback_raw(name, &loaded); break; default: /* parse the file header */ printf("file_type:%d\n",file_type); if (playback_au(name, &loaded) < 0 && playback_voc(name, &loaded) < 0 && playback_wave(name, &loaded) < 0) playback_raw(name, &loaded); /* should be raw data */ break; } if (fd != fileno(stdin)) close(fd); } 其四个函数的额处理差异,主要是处理了文件头,比如播放的为PCM或者WAV格式的文件,而给定的参数-t au/voc 将不会进行播放。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/204623.html原文链接:https://javaforall.net
