Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The amr file convert from wav , it can't be played #443

Closed
jolincheng opened this issue May 31, 2022 · 8 comments
Closed

The amr file convert from wav , it can't be played #443

jolincheng opened this issue May 31, 2022 · 8 comments
Assignees
Labels
android Affect Android platform ffmpeg-bug Something isn't right in ffmpeg source code fixed-in-v5.1 flutter Affect flutter platform react-native Affect react-native platform v4.5.1 Affects v4.5.1 release

Comments

@jolincheng
Copy link

jolincheng commented May 31, 2022

Description

I convert wav to amr, the 'session.getReturnCode()' is 'isValueSuccess' ,but i get media formation from 'FFprobeKit',the result is "Invalid data found when processing input",i can get nothing about the amr media formation. I try to print mp3,wav,mp4,that all is right ,so i think is the problem with 'libopencore-amrnb'.

Expected behavior
i want convert success,and amr can be played success

Current behavior
convert success,but file is unusefull

Environment

Platform: Flutter
Architecture: arm64e
Version: 14.6
Source branch: main
Xcode version: 13.3
Cocoapods version: 1.11.3
Android Studio version: 2021.1

Following is the 'pubspec.yaml' file’s configuration:
ffmpeg_kit_flutter_full: 4.5.1

Following is the convert log

flutter: wavToAmr commond == -i /private/var/mobile/Containers/Data/Application/391D6894-6696-4066-B1DA-84A7320FDB51/tmp/250087e7e5903735c4a7c27a9db7dcec.wav -ab 12.2k -ar 8000 -ac 1 /var/mobile/Containers/Data/Application/391D6894-6696-4066-B1DA-84A7320FDB51/Library/Caches/250087e7e5903735c4a7c27a9db7dcec.amr
flutter: returnCode===log=ffmpeg version v4.5-dev-3393-g30322ebe3c
flutter: returnCode===log= Copyright (c) 2000-2021 the FFmpeg developers
flutter: returnCode===log=
flutter: returnCode===log= built with Apple clang version 13.0.0 (clang-1300.0.29.30)
flutter: returnCode===log= configuration: --cross-prefix=arm64-ios-darwin- --sysroot=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk --prefix=/Users/taner/Projects/ffmpeg-kit/prebuilt/apple-ios-arm64/ffmpeg --pkg-config=/opt/homebrew/bin/pkg-config --enable-version3 --arch=aarch64 --cpu=armv8 --target-os=darwin --enable-neon --enable-asm --ar=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar --cc=clang --cxx=clang++ --as='/Users/taner/Projects/ffmpeg-kit/.tmp/gas-preprocessor.pl -arch aarch64 -- clang -arch arm64 -target arm64-apple-ios12.1 -march=armv8-a+crc+crypto -mcpu=generic -DFFMPEG_KIT_ARM64 -Wno-unused-function -Wno-deprecated-declarations -fstrict-aliasing -fembed-bitcode -DIOS -DFFMPEG_KIT_BUILD_DATE=20220114 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk -Oz -miphoneos-version-min=12.1 -I/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/usr/include' --ranlib=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib --strip=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/strip --nm=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/nm --extra-ldflags='-miphoneos-version-min=12.1' --disable-autodetect --enable-cross-compile --enable-pic --enable-inline-asm --enable-optimizations --enable-swscale --enable-shared --disable-static --install-name-dir='@rpath' --enable-pthreads --disable-v4l2-m2m --disable-outdev=v4l2 --disable-outdev=fbdev --disable-indev=v4l2 --disable-indev=fbdev --enable-small --disable-xmm-clobber-test --disable-debug --disable-neon-clobber-test --disable-programs --disable-postproc --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-sndio --disable-schannel --disable-securetransport --disable-xlib --disable-cuda --disable-cuvid --disable-nvenc --disable-vaapi --disable-vdpau --disable-alsa --disable-cuda --disable-cuvid --disable-nvenc --disable-vaapi --disable-vdpau --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-gmp --enable-gnutls --enable-libmp3lame --enable-libass --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libxml2 --enable-libopencore-amrnb --enable-libshine --enable-libspeex --enable-libdav1d --enable-libkvazaar --enable-libilbc --enable-libopus --enable-libsnappy --enable-libsoxr --enable-libtwolame --disable-sdl2 --enable-libvo-amrwbenc --enable-libzimg --disable-openssl --enable-zlib --enable-audiotoolbox --disable-outdev=audiotoolbox --enable-bzlib --enable-videotoolbox --enable-avfoundation --enable-iconv --disable-coreimage --disable-appkit --disable-opencl --disable-opengl
flutter: returnCode===log= libavutil 57. 13.100 / 57. 13.100
flutter: returnCode===log= libavcodec 59. 15.102 / 59. 15.102
flutter: returnCode===log= libavformat 59. 10.100 / 59. 10.100
flutter: returnCode===log= libavdevice 59. 1.100 / 59. 1.100
flutter: returnCode===log= libavfilter 8. 21.100 / 8. 21.100
flutter: returnCode===log= libswscale 6. 1.102 / 6. 1.102
flutter: returnCode===log= libswresample 4. 0.100 / 4. 0.100
flutter: returnCode===log=Guessed Channel Layout for Input Stream #0.0 : mono
flutter: returnCode===log=Input #0, wav, from '/private/var/mobile/Containers/Data/Application/391D6894-6696-4066-B1DA-84A7320FDB51/tmp/250087e7e5903735c4a7c27a9db7dcec.wav':
flutter: returnCode===log= Duration:
flutter: returnCode===log=00:00:04.63
flutter: returnCode===log=, bitrate:
flutter: returnCode===log=135 kb/s
flutter: returnCode===log=
flutter: returnCode===log= Stream #0:0
flutter: returnCode===log=: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 8000 Hz, mono, s16, 128 kb/s
flutter: returnCode===log=
flutter: returnCode===log=[pcm_s16le @ 0x1651918e0] The "sub_text_format" option is deprecated: Deprecated, does nothing
flutter: returnCode===log=Stream mapping:
flutter: returnCode===log= Stream #0:0 -> #0:0
flutter: returnCode===log= (pcm_s16le (native) -> amr_nb (libopencore_amrnb))
flutter: returnCode===log=
flutter: returnCode===log=Press [q] to stop, [?] for help
flutter: returnCode===log=Output #0, amr, to '/var/mobile/Containers/Data/Application/391D6894-6696-4066-B1DA-84A7320FDB51/Library/Caches/250087e7e5903735c4a7c27a9db7dcec.amr':
flutter: returnCode===log= Metadata:
flutter: returnCode===log= encoder :
flutter: returnCode===log=Lavf59.10.100
flutter: returnCode===log=
flutter: returnCode===log= Stream #0:0
flutter: returnCode===log=: Audio: amr_nb, 8000 Hz, mono, s16, 12 kb/s
flutter: returnCode===log=
flutter: returnCode===log= Metadata:
flutter: returnCode===log= encoder :
flutter: returnCode===log=Lavc59.15.102 libopencore_amrnb
flutter: returnCode===log=
flutter: returnCode===Statistics=233
flutter: returnCode===log=size= 0kB time=00:00:00.23 bitrate= 13.3kbits/s speed=N/A
flutter: returnCode===Statistics=4633
flutter: returnCode===log=size= 7kB time=00:00:04.63 bitrate= 12.8kbits/s speed= 246x
flutter: returnCode===log=video:0kB audio:7kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead:
flutter: returnCode===log=0.067349%

Folloing is the ffprobe infomation

flutter: getMediaInformation====null
[VERBOSE-2:ui_dart_state.cc(198)] Unhandled Exception: NoSuchMethodError: The method 'getFilename' was called on null.

@tanersener
Copy link
Collaborator

tanersener commented Jun 1, 2022

There is not enough information to make a comment about this. We don't have clear instructions to test and reproduce this case.

@tanersener tanersener added needs-more-details We need more details to understand what the problem is flutter Affect flutter platform v4.5.1 Affects v4.5.1 release labels Jun 1, 2022
@jolincheng
Copy link
Author

Flutter ios ,you convert wav to amr,then use 'FFprobeKit' print amr media infomation, you will know what i say

@jolincheng
Copy link
Author

The right file you use 'FFprobeKit' print media infomation, you can get all media infomation, but the amr file which conver from wav used FFmpeg can not get any media infomation

@jolincheng
Copy link
Author

@tanersener
Copy link
Collaborator

We have lots of issues reported in this project, where API methods are not used correctly. Because of that, we expect users to share their source code. To make sure that API methods are used in the right way and the issue is worth spending time on. We have to do this since we don't have unlimited time and we cannot guess what developers are doing in their apps.

This is clearly explained in #215.

I don't see any source code here. So, there is nothing we can do.

@wiikzz
Copy link

wiikzz commented Jul 25, 2022

I meet the same problem in Android.

将任何格式的音文件转换成“amr”格式,可以执行成功,但生成的文件播放失败,AudioPlayer无法读取,将该文件导出到电脑上,也无法播放,显示文件有问题。
convert any format audio to 'amr' format, it will success, but the output result file can not play. export the file to my computer to play, it still can't, shows not a media file.

dependence:

implementation 'com.arthenica:ffmpeg-kit-full:4.5.1-1.LTS'

some logic code:

    private const val SPACE = " "    
    /** 获取音频格式转换命令 */  //  FFmpegOperateManager.getAudioFormatConvertCommand 方法
    fun getAudioFormatConvertCommand(fromPath: String?, toPath: String?): String? {
        val fromFormat = RecordSupportedHelper.getAudioFileFormat(fromPath) ?: return null
        val toFormat = RecordSupportedHelper.getAudioFileFormat(toPath) ?: return null
        if (fromFormat == toFormat) { return null }
        val commandBuilder = StringBuilder()
        commandBuilder.append("-hide_banner -y")
        // 输入文件前的参数组织
        when (fromFormat) {
            RecordAudioFormat.PCM -> {
                commandBuilder.append(SPACE).append("-f s16be -acodec pcm_s16le")
            }
            else -> { /** do nothing */ }
        }
        // 输入文件
        commandBuilder.append(SPACE).append("-i").append(SPACE).append(fromPath)

        // 输出文件前的参数组织
        when (toFormat) {
            RecordAudioFormat.PCM -> {
                commandBuilder.append(SPACE).append("-f s16be -ar 16000 -ac 1 -acodec pcm_s16le")
            }
            RecordAudioFormat.AMR -> {
                commandBuilder.append(SPACE).append("-ar 8000 -ac 1")
            }
            else -> {
                commandBuilder.append(SPACE).append("-ar 16000 -ac 1")
            }
        }
        // 输入文件
        commandBuilder.append(SPACE).append(toPath)
        return commandBuilder.toString()
    }

    // FFmpegOperateManager.executeFFmpegCommand 方法
    /** 执行ffmpeg命令 */
    fun executeFFmpegCommand(command: String?, complete: (Boolean) -> Unit) {
        if (command.isNullOrEmpty()) { complete(false); return }
        FFmpegKit.executeAsync(command,
            { session ->
                if (ReturnCode.isSuccess(session?.returnCode)) {
                    mHandler.post { complete(true) }
                } else {
                    mHandler.post { complete(false) }
                }
            },
            { log ->
                Trace.e(log.message)
            },
            { statistic ->
                Trace.e(statistic.toString())
            }
        )
    }

    //  这是调用的地方
    fun startToFormatAudioFile(audioPath: String?, toFormat: RecordAudioFormat): Boolean {
        if (audioPath.isNullOrEmpty()) { return false }
        // 获取目标文件
        val destFile = RecordMediaNameHelper.generateMediaFile(audioPath,
            RecordStoreFileManager.getStoreAudioCommonDir(), toFormat, RecordFuncType.AUDIO_FORMAT)
        if (destFile == null) { return false }
        // 获取ffmpeg命令
        val command = FFmpegOperateManager.getAudioFormatConvertCommand(audioPath, destFile.absolutePath)
        // 执行命令
        FFmpegOperateManager.executeFFmpegCommand(command) {
            if (it) { saveInDatabaseAfterFFmpegOperate(destFile) } else {
                mFormatState.postValue(false)
            }
        }
        return true
    }

下面是执行一次示例的日志
Below is the log of executing the example once

2022-07-25 19:43:34.572 5079-5079/xxxxxx D/AudioFucFormatViewModel-wiikzz: command: -hide_banner -y -i /storage/emulated/0/Android/data/xxxxxx/files/audio/common/abc.mp3 -ar 8000 -ac 1 /storage/emulated/0/Android/data/xxxxxx/files/audio/common/转格式_abc(2).amr
2022-07-25 19:43:34.585 5079-5079/xxxxxx I/ffmpeg-kit: Loading ffmpeg-kit.
2022-07-25 19:43:34.606 5079-5079/xxxxxx I/ffmpeg-kit: Loaded ffmpeg-kit-full-arm64-v8a-4.5.1-lts-20220101.
2022-07-25 19:43:34.608 5079-5513/xxxxxx D/ffmpeg-kit: Async callback block started.
2022-07-25 19:43:34.618 5079-5513/xxxxxx E/wiikzz: Input #0, mp3, from '/storage/emulated/0/Android/data/xxxxxx/files/audio/common/abc.mp3':
2022-07-25 19:43:34.619 5079-5513/xxxxxx E/wiikzz: Metadata:
2022-07-25 19:43:34.620 5079-5513/xxxxxx E/wiikzz: encoder :
2022-07-25 19:43:34.621 5079-5513/xxxxxx E/wiikzz: Lavf58.12.100
2022-07-25 19:43:34.623 5079-5513/xxxxxx E/wiikzz:
2022-07-25 19:43:34.624 5079-5513/xxxxxx E/wiikzz: Duration:
2022-07-25 19:43:34.625 5079-5513/xxxxxx E/wiikzz: 00:00:45.58
2022-07-25 19:43:34.626 5079-5513/xxxxxx E/wiikzz: , start:
2022-07-25 19:43:34.626 5079-5079/xxxxxx D/DecorView: createDecorCaptionView windowingMode:1 mWindowMode 1 isFullscreen: true
2022-07-25 19:43:34.627 5079-5513/xxxxxx E/wiikzz: 0.069063
2022-07-25 19:43:34.628 5079-5513/xxxxxx E/wiikzz: , bitrate:
2022-07-25 19:43:34.629 5079-5513/xxxxxx E/wiikzz: 24 kb/s
2022-07-25 19:43:34.630 5079-5513/xxxxxx E/wiikzz:
2022-07-25 19:43:34.631 5079-5513/xxxxxx E/wiikzz: Stream #0:0
2022-07-25 19:43:34.632 5079-5513/xxxxxx E/wiikzz: : Audio: mp3, 16000 Hz, mono, fltp, 24 kb/s
2022-07-25 19:43:34.633 5079-5513/xxxxxx E/wiikzz:
2022-07-25 19:43:34.634 5079-5513/xxxxxx E/wiikzz: [mp3float @ 0x7da139f800] The "sub_text_format" option is deprecated: Deprecated, does nothing
2022-07-25 19:43:34.635 5079-5513/xxxxxx E/wiikzz: Stream mapping:
2022-07-25 19:43:34.636 5079-5513/xxxxxx E/wiikzz: Stream #0:0 -> #0:0
2022-07-25 19:43:34.637 5079-5513/xxxxxx E/wiikzz: (mp3 (mp3float) -> amr_nb (libopencore_amrnb))
2022-07-25 19:43:34.638 5079-5513/xxxxxx E/wiikzz:
2022-07-25 19:43:34.639 5079-5513/xxxxxx E/wiikzz: Press [q] to stop, [?] for help
2022-07-25 19:43:34.640 5079-5513/xxxxxx E/wiikzz: [libopencore_amrnb @ 0x7da143a800] bitrate not supported: use one of 4.75k, 5.15k, 5.90k, 6.70k, 7.40k, 7.95k, 10.20k, 12.20k, using 12.20k
2022-07-25 19:43:34.641 5079-5513/xxxxxx E/wiikzz: Output #0, amr, to '/storage/emulated/0/Android/data/xxxxxx/files/audio/common/转格式_abc(2).amr':
2022-07-25 19:43:34.642 5079-5513/xxxxxx E/wiikzz: Metadata:
2022-07-25 19:43:34.643 5079-5513/xxxxxx E/wiikzz: encoder :
2022-07-25 19:43:34.643 5079-5513/xxxxxx E/wiikzz: Lavf59.10.100
2022-07-25 19:43:34.644 5079-5513/xxxxxx E/wiikzz:
2022-07-25 19:43:34.645 5079-5513/xxxxxx E/wiikzz: Stream #0:0
2022-07-25 19:43:34.646 5079-5513/xxxxxx E/wiikzz: : Audio: amr_nb, 8000 Hz, mono, s16, 128 kb/s
2022-07-25 19:43:34.647 5079-5513/xxxxxx E/wiikzz:
2022-07-25 19:43:34.647 5079-5513/xxxxxx E/wiikzz: Metadata:
2022-07-25 19:43:34.648 5079-5513/xxxxxx E/wiikzz: encoder :
2022-07-25 19:43:34.649 5079-5513/xxxxxx E/wiikzz: Lavc59.15.102 libopencore_amrnb
2022-07-25 19:43:34.650 5079-5513/xxxxxx E/wiikzz:
2022-07-25 19:43:34.651 5079-5513/xxxxxx E/wiikzz: Statistics{sessionId=1, videoFrameNumber=0, videoFps=0.0, videoQuality=0.0, size=5, time=0, bitrate=-1.0, speed=0.0}
2022-07-25 19:43:34.652 5079-5513/xxxxxx E/wiikzz: size= 0kB time=00:00:00.00 bitrate=N/A speed= 0x
2022-07-25 19:43:34.987 5079-5134/xxxxxx I/crashsdk: crashsdk uploading logs
2022-07-25 19:43:35.070 5079-5513/xxxxxx E/wiikzz: Statistics{sessionId=1, videoFrameNumber=0, videoFps=0.0, videoQuality=0.0, size=72837, time=45513, bitrate=12.80263656587295, speed=101.25101740368267}
2022-07-25 19:43:35.070 5079-5513/xxxxxx E/wiikzz: size= 71kB time=00:00:45.51 bitrate= 12.8kbits/s speed= 101x
2022-07-25 19:43:35.071 5079-5513/xxxxxx E/wiikzz: video:0kB audio:71kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead:
2022-07-25 19:43:35.071 5079-5513/xxxxxx E/wiikzz: 0.006865%
2022-07-25 19:43:35.071 5079-5513/xxxxxx E/wiikzz:

image

这是使用FFmpegKit转换后的文件跟 正常转换后的文件数据的一个对比,好像少了一个字节数据0a
This is a comparison between the file converted using FFmpegKit and the normal converted file data, it seems that one byte of data 0a is missing

我使用下面的方法间接解决了这个问题,希望可以尽快修改好。
I solved this problem indirectly by using the following method, I hope it can be fixed as soon as possible

    private val sAmrFileHeaderArray = byteArrayOf(35, 33, 65, 77, 82, 10)
    private fun byteArrayCompare(src: ByteArray, another: ByteArray): Pair<Boolean, Int> {
        if (src.size != another.size) return Pair(false, 0)
        for (i in src.indices) {
            if (src[i] != another[i]) {
                return Pair(false, i)
            }
        }
        return Pair(true, 0)
    }
    fun repairFFmpegKitAmrFile(amrFile: File?) {
        if (amrFile == null || !amrFile.isFile) { return }
        if (!amrFile.extension.equals("amr", true)) {
            return
        }

        val tempFileName = "temp_${amrFile.name}"
        val tempFile = File(amrFile.parent, tempFileName)

        // 检查amr文件格式是否正确
        var inputStream: FileInputStream? = null
        var outputStream: OutputStream? = null
        try {
            inputStream = FileInputStream(amrFile)
            val byteArray = ByteArray(sAmrFileHeaderArray.size)
            inputStream.read(byteArray)
            val (same, index) = byteArrayCompare(byteArray, sAmrFileHeaderArray)
            if (same) { return }

            val dataBuffer = ByteArray(8 * 1024)
            FileUtils.createOrExistsFile(tempFile)
            outputStream = BufferedOutputStream(FileOutputStream(tempFile))
            // write header
            outputStream.write(sAmrFileHeaderArray)
            outputStream.write(byteArray, index, byteArray.size - index)
            var readSize: Int
            while (inputStream.read(dataBuffer).also { readSize = it } != -1) {
                outputStream.write(dataBuffer, 0, readSize)
            }
            outputStream.flush()

            // 将原文件删除
            FileUtils.delete(amrFile)
            FileUtils.rename(tempFile, amrFile.name)
        } catch (t: Throwable) {
            return
        } finally {
            closeStream(inputStream)
            closeStream(outputStream)
        }
    }

@tanersener tanersener added ffmpeg-bug Something isn't right in ffmpeg source code android Affect Android platform react-native Affect react-native platform and removed needs-more-details We need more details to understand what the problem is labels Jul 29, 2022
@tanersener tanersener self-assigned this Jul 29, 2022
@tanersener
Copy link
Collaborator

@wiikzz Thanks for providing details about this case. It seems like there is a bug there. It is coming from ffmpeg. So, I marked this case as ffmpeg-bug for 4.5.1.

4.5 don't have this problem. If you are affected from this either downgrade to 4.5 or wait for the new release which will be released in 1-2 weeks.

@tanersener tanersener removed their assignment Aug 26, 2022
@tanersener tanersener self-assigned this Sep 12, 2022
@tanersener tanersener added development-branch Affects development branch fixed-on-development Fixed on the development branch. Not released yet. and removed development-branch Affects development branch labels Sep 12, 2022
@tanersener
Copy link
Collaborator

This issue is fixed on the ffmpeg version we depend on the development branch.

@tanersener tanersener added fixed-in-v5.1 and removed fixed-on-development Fixed on the development branch. Not released yet. labels Oct 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
android Affect Android platform ffmpeg-bug Something isn't right in ffmpeg source code fixed-in-v5.1 flutter Affect flutter platform react-native Affect react-native platform v4.5.1 Affects v4.5.1 release
Projects
None yet
Development

No branches or pull requests

3 participants