第十六节 关于音频的裁剪 边播边裁

边播边裁

image.png

先判断下是否满足裁剪条件,如果满足的话将解码获得的pcm数据返回给上层记录下来
HFFmpeg.cpp

jboolean HFFmpeg::canCut(JNIEnv *pEnv, jint startTime, jint endTime, jboolean savePcm) {
    if(startTime>=0&&startTime<=duration&&startTime<=endTime)
    {
        hAudio->isCut=true;
        hAudio->end_time=endTime;
        hAudio->showPcm=savePcm;
        seek(startTime);
        return true;
    }
    return false;
}

HAudio.cpp

void pcmBufferCallBack(SLAndroidSimpleBufferQueueItf bf, void * context)
{
    HAudio *wlAudio = (HAudio *) context;
    if(wlAudio != NULL)
    {
        if(LOG_DEBUG)
        {
            LOGI("循环调用重采样");
        }
        int buffersize = wlAudio->getSoundTouchData();

        //int buffersize = wlAudio->resampleAudio((void **) &wlAudio->out_buffer);;
        if(buffersize > 0)
        {
            int out_channels=av_get_channel_layout_nb_channels(AV_CH_LAYOUT_STEREO);
            int totalBytes=buffersize*out_channels*av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);
            wlAudio->clock+=totalBytes/(double)(wlAudio->sample_rate*2*2);
            //我们0.1s回调一次
            if(wlAudio->clock-wlAudio->last_time>0.1)
            {
                wlAudio->last_time=wlAudio->clock;
                //回调Java层显示时间
                wlAudio->callBackJava->onShowTime(CHILD_THREAD,wlAudio->duration,wlAudio->clock);

            }
            wlAudio->bufferQueue->putBuffer(wlAudio->sampleBuffer, totalBytes);
            //(* wlAudio-> pcmBufferQueue)->Enqueue( wlAudio->pcmBufferQueue, (char *) wlAudio-> buffer, buffersize);
            //注意这儿的代码变化
            //(* wlAudio-> pcmBufferQueue)->Enqueue( wlAudio->pcmBufferQueue, (char *) wlAudio-> sampleBuffer, buffersize*out_channels*av_get_bytes_per_sample(AV_SAMPLE_FMT_S16));
            (* wlAudio-> pcmBufferQueue)->Enqueue( wlAudio->pcmBufferQueue, (char *) wlAudio-> sampleBuffer, totalBytes);

            if(wlAudio->isCut)
            {
                if(wlAudio->showPcm)
                {
                    //返回pcm数据给应用层
                    wlAudio->callBackJava->onCallPcmInfo(wlAudio->sampleBuffer, totalBytes);


                }
                if(wlAudio->clock>wlAudio->end_time)
                {
                    LOGI("裁剪退出");
                    wlAudio->hPlayStatus->exit=true;
                }

            }
        }
    }
}

Player.java

private File cutFile=null;
    private FileOutputStream fileOutputStream;
    public void startCutAudio() {
        if(canCut(100,110,true))
        {
            try {
                cutFile=new File(Environment.getExternalStorageDirectory()+"/cut.pcm");
                fileOutputStream=new FileOutputStream(cutFile);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
        else
        {

        }

    }

    private native boolean canCut(int startTime,int endTime,boolean savePCM);

    private void onCallPcmInfo(byte[] data,int size)
    {
        try {
            if(fileOutputStream!=null)
            {
                fileOutputStream.write(data);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * 上层调用
     * @param path
     */
    public void cutAudio(String path) {
        isCut=true;
        startDecode(path);
    }
public boolean isCut=false;
    public void onPrepared(String msg,int total)
    {

        this.total=total;
        Log.e("VoicePlayer","[Java]msg:"+msg);
        //是否在裁剪
        if(isCut)
        {
            isCut=false;
            startCutAudio();
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                start();
            }
        }).start();
    }

MainActivity.java

public void startCutAudio(View view) {
        player.cutAudio(Environment.getExternalStorageDirectory()+"/lame.mp3");
    }
image.png

你可能感兴趣的:(第十六节 关于音频的裁剪 边播边裁)