【问题标题】:How to record sound in the background in android using Delphi 10如何使用 Delphi 10 在 android 的后台录制声音
【发布时间】:2016-08-31 20:48:33
【问题描述】:

地狱,我正在尝试测试 Delphi 10 Android 后台服务,我正在尝试使用本地服务在后台录制声音,但是,当该服务开始将声音录制到 Test.caf 时,我的代码: 应用程序

  procedure TForm1.Button1Click(Sender: TObject);
  begin
   TLocalServiceConnection.StartService('RecService');

服务代码:

  function TAndroidServiceDM.AndroidServiceStartCommand(const Sender:     TObject;
 const Intent: JIntent; Flags, StartId: Integer): Integer;
 begin
 Result := TJService.JavaClass.START_STICKY;
 FMicrophone := TCaptureDeviceManager.Current.DefaultAudioCaptureDevice;

 { and attempt to record to 'test.caf' file }
 FMicrophone.FileName := '/sdcard/1/test.caf';
 FMicrophone.StartCapture;
 sleep(5000);
     FMicrophone.StopCapture;

任何帮助都非常感谢。

【问题讨论】:

    标签: android service firemonkey delphi-xe


    【解决方案1】:

    RAD Studio 中的 Android 服务不适用于 FMX... 模块。要使用媒体需要使用低级模块。

    我意识到这个方法的问题(希望它有用):

    uses
      ...
      AndroidApi.JNI.Media, // JMediaRecorder
      AndroidApi.Timer, // Timer
      ...;
    
    Const
      TimerInterval = 1000;
      TimerCounterSecLimit = 10;
    
    type
      TDM = class(TAndroidService)
        ...
      private
        FTimerHandle: Integer;
        FRecording: Boolean;
    
        procedure StartRecord;
        procedure StopRecord;
    
        procedure StartTimer;
        procedure StopTimer;
      public
        FAudioRec: JMediaRecorder;
      end;
    
    procedure TDM.AndroidServiceCreate(Sender: TObject);
    begin
      FTimerHandle := 0;
      FTimerCounter := 0;
      FRecording := false;
    end;
    
    procedure TDM.AndroidServiceDestroy(Sender: TObject);
    begin
      StopTimer;
      StopRecord;
    end;
    
    function TDM.AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent; Flags, StartId: Integer): Integer;
    begin
      if Intent.getAction.equalsIgnoreCase(StringToJString('StopIntent')) then
      begin
        StopTimer;
        StopRecord;
        Result := TJService.JavaClass.START_NOT_STICKY; // don't reload service
        Log('- service stoped', []);
      end
      else begin
        if not FRecording then
        begin
            Log('... sound record to be started', []);
            StartRecord;
            StartTimer;
        end;
    
        Result := TJService.JavaClass.START_STICKY; // rerun service if it stops
        Log('+ Service started', []);
      end;
    end;
    
    procedure TDM.StartRecord;
    begin
      StopRecord;
    
      FAudioRec := TJMediaRecorder.Create;
      FAudioRec.setAudioSource(TJMediaRecorder_AudioSource.JavaClass.MIC);
      FAudioRec.setOutputFormat(TJMediaRecorder_OutputFormat.JavaClass.THREE_GPP);
      FAudioRec.setAudioEncoder(TJMediaRecorder_AudioEncoder.JavaClass.AMR_NB);
      FAudioRec.setOutputFile(StringToJString(TPath.Combine(TPath.GetSharedMusicPath, 'myrecord.3gp')));
      try
        FAudioRec.Prepare();
        FAudioRec.start;
        FRecording := True;
        Log('+ Start record to %s', [TPath.Combine(TPath.GetSharedMusicPath, 'myrecord.3gp')]);
      except
        on E: Exception do
          Log('- Error in mic recording: %s', [E.Message]);
      end;
    end;
    
    procedure TDM.StopRecord;
    begin
      if Assigned(FAudioRec) then
      begin
        if FRecording then
        begin
          FRecording := false;
          try
            FAudioRec.stop();
            FAudioRec.release();
            Log('- Mic recording is stoped');
          except
            on E: Exception do
              Log('- Error in mic stop recording: %s', [E.Message]);
          end;
        end;
      end
      else
      begin
        FRecording := false;
      end;
    end;
    
    procedure TDM.WaitComplete(TimerId: Integer);
    begin
      if FTimerCounter < TimerCounterSecLimit then
      begin
        Log('+++ Timer is triggered %d time.', [FTimerCounter]);
        inc(FTimerCounter);
      end
      else
        StopTimer;
    end;
    
    procedure TDM.StartTimer;
    begin
      FTimerCounter := 0;
      if FTimerHandle = 0 then
      begin
        FTimerHandle := AndroidTimerCreate;
        AndroidTimerSetInterval(FTimerHandle, TimerInterval);
      end;
      AndroidTimerSetHandler(WaitComplete);
    
      Log('+ Timer started', []);
    end;
    
    procedure TDM.StopTimer;
    begin
      if FTimerHandle > 0 then
      begin
        Log('... MIC recording to be stopped');
        StopRecord;
    
        AndroidTimerSetHandler(nil);
        Log('- Timer stoped', []);
      end;
    end;
    
    end.
    

    【讨论】:

      【解决方案2】:

      您启用了哪些权限? 服务是否有效,声音文件是否已创建?

      1. 它需要启动一个 TThread 而不是 Sleep()。

      2. Module FMX.Media.pas->FMX.Media.Android.pas 使用 Android 活动,在 Android 服务中不起作用。并且服务不应该运行。它需要使用替代方法来处理 AudioCaptureDevice。

      【讨论】:

      • 录制权限,是的,它可以工作,没有创建声音文件!,服务仍在运行,直到被用户终止
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-25
      相关资源
      最近更新 更多