[Gambas-user] gstreamer and aac format

System64 Development 64xcode at gmail.com
Thu Jan 11 13:36:31 CET 2024


Hi,

I'm trying to record audio in aac format [1] with gstreamer using a 
class that Claus kindly shared with me.
I have tried some of the plugins listed on the gstreamer site [2] but I 
can't get the audio in that format.
Any idea?
I leave the class as an attachment in case anyone wants to do some testing.

[1] https://en.wikipedia.org/wiki/Advanced_Audio_Coding

[2] 
https://gstreamer.freedesktop.org/documentation/plugins_doc.html?gi-language=c

Thanks.

Martin.
-------------- next part --------------
' Gambas class file

'==============================================================================
'LICENSING
'
'This class is published under following licensing conditions:
'
' NEW BSD LICENSE
'
' Copyright (c) 2023 Claus Dietrich.
' All rights reserved
'
' Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
'
' 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
'
' 2. Redistributions in Binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
'    documentation and / or other materials provided with the distribution.
'
' 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
'    software without specific prior written permission.

' DISCLAIMER
' THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
' THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
' CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
' PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
' LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
' SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY Of SUCH DAMAGE.
'
'==============================================================================
Export' Gambas class file
'******************************************************************************
' Constants
'******************************************************************************
Public Const mp3 As Integer = 1
Public Const ogg As Integer = 2
Public Const wav As Integer = 3
Public Const aac As Integer = 4
Public Const AlsaDevice As Integer = 1
Public Const AudioStream As Integer = 2
'******************************************************************************
' Properties
'******************************************************************************
Property Device As String                               'Alsa-Device, i.e."alsa_output.pci-0000_00_1b.0.analog-stereo.monitor"
Property Read Devices As String[]                       'Provides a list of available alsa-devices
Property StreamURL As String                            'URL of the audio stream
Property Path As String                                 'Directory where the output file shall be stored
Property Base As String                                 'Base name
Property Record As Boolean                              'True = Start Recording, False= Stop Recording
Property Source As String                               'Either AlsaDevice or AudioStream (see above constants)
Property RecordingFormat As Integer                     'mp3, ogg or wav (see above constants)

'******************************************************************************
' Events
'******************************************************************************
Event Error(Data As String)
'******************************************************************************
' Variables
'******************************************************************************
Private $Device As String
Private $StreamURL As String
Private $Path As String = "/home/" & User.Name          'Directory of output file, default=user home directory
Private $Base As String
Private $Record As Boolean
Private $Source As String = 1                           '1=AlsaDevice, 2=AudioStream
Private $ErrMsg As String
Private $RecordingFormat As Integer = 1                 '1=mp3, 2=ogg, 3=wav
Private $TempFilePath As String

Private pl As MediaPipeline
Private src As MediaControl
Private fmt As MediaControl
Private enc As MediaControl
Private snk As MediaControl
Private mux As MediaControl

Public Sub _new()

  Dim s As String

  If Not Exist("/bin/pulseaudio") Then
    $ErrMsg = "pulseaudio is required but not installed."
    Message.Error($ErrMsg)
    Return
  Endif

  Shell "pacmd list-sources | grep 'name:' | cut -d" & Chr$(34) & " " & Chr$(34) & " -f2 | grep '.monitor' " To s
  s = Replace(s, "<", "")
  s = Replace(s, ">", "")
  $Device = Trim(s)

End

Public Sub _ready()

  If $ErrMsg > "" Then
    Raise Error($ErrMsg)
  End If

End

Private Function Device_Read() As String

  Return $Device

End

Private Sub Device_Write(Value As String)

  $Device = Value

End

Private Function Path_Read() As String

  Return $Path

End

Private Sub Path_Write(Value As String)

  $Path = Value

End

Private Function Record_Read() As Boolean

  Return $Record

End

Private Sub Record_Write(Value As Boolean)

  Dim s As String

  Print "$Source:"; $Source

  If Value = True And $Record = False Then
    $Record = True
    Assemble_Pipe()
    pl.play
  Else If Value = False And $Record = True
    $Record = False
    pl.Stop
    If $RecordingFormat = mp3 Then
      Copy $TempFilePath To $Path &/ $Base & ".mp3"
    Else If $RecordingFormat = ogg Then
      Copy $TempFilePath To $Path &/ $Base & ".ogg"
    Else If $RecordingFormat = wav Then
      Copy $TempFilePath To $Path &/ $Base & ".wav"
    Else If $RecordingFormat = aac Then
      Copy $TempFilePath To $Path &/ $Base & ".aac"
    Endif
  End If

End

Private Function Source_Read() As String

  Return $Source

End

Private Sub Source_Write(Value As String)

  $Source = Value

End

Private Function RecordingFormat_Read() As Integer

  Return $RecordingFormat

End

Private Sub RecordingFormat_Write(Value As Integer)

  $RecordingFormat = Value

End

Public Function GetDevices() As String[]

  Dim s As String

  Shell "pacmd list-sources | grep 'name:' | cut -d" & Chr$(34) & " " & Chr$(34) & " -f2" To s
  s = Replace(s, "<", "")
  s = Replace(s, ">", "")
  Return Split(Trim(s), gb.LF)

End

Private Sub Assemble_Pipe()

  'Set a path for a temporary audio file
  $TempFilePath = Temp$()

  If $Source = AlsaDevice Then
    If $RecordingFormat = mp3 Then
      pl = New MediaPipeline
      src = New MediaControl(pl, "pulsesrc")
      src["device"] = $Device
      fmt = New MediaControl(pl, "audio/x-raw,rate=44100,channels=2")
      enc = New MediaControl(pl, "lamemp3enc")
      enc["quality"] = 0
      enc["target"] = "bitrate"
      enc["bitrate"] = 128 ' I change here
      enc["cbr"] = True
      mux = New MediaControl(pl, "id3v2mux")
      snk = New MediaControl(pl, "filesink")
      snk["location"] = $TempFilePath
      src.LinkTo(fmt)
      fmt.LinkTo(enc)
      enc.LinkTo(mux)
      mux.LinkTo(snk)
    Else If $RecordingFormat = ogg Then
      pl = New MediaPipeline
      src = New MediaControl(pl, "pulsesrc")
      src["device"] = $Device
      fmt = New MediaControl(pl, "audio/x-raw,rate=44100,channels=2")
      enc = New MediaControl(pl, "vorbisenc")
      enc["quality"] = 0.3   '0=worst, 0.3=default, 1=best (only 0.3 as default is documented, 0 and 1 was tested)
      mux = New MediaControl(pl, "oggmux")
      snk = New MediaControl(pl, "filesink")
      snk["location"] = $TempFilePath
      src.LinkTo(fmt)
      fmt.LinkTo(enc)
      enc.LinkTo(mux)
      mux.LinkTo(snk)
    Else If $RecordingFormat = wav Then
      pl = New MediaPipeline
      src = New MediaControl(pl, "pulsesrc")
      src["device"] = $Device
      fmt = New MediaControl(pl, "audio/x-raw,rate=44100,channels=2")
      enc = New MediaControl(pl, "wavenc")
      snk = New MediaControl(pl, "filesink")
      snk["location"] = $TempFilePath
      src.LinkTo(fmt)
      fmt.LinkTo(enc)
      enc.LinkTo(snk)
    Else If $RecordingFormat = aac Then
      pl = New MediaPipeline
      src = New MediaControl(pl, "pulsesrc")
      src["device"] = $Device
      fmt = New MediaControl(pl, "audio/x-raw,rate=44100,channels=2")
      enc = New MediaControl(pl, "faac")
      enc["quality"] = 0
      'enc["target"] = "bitrate"
      enc["bitrate"] = 128 ' I change here
      'enc["cbr"] = True
      mux = New MediaControl(pl, "id3v2mux")
      snk = New MediaControl(pl, "filesink")
      snk["location"] = $TempFilePath
      src.LinkTo(fmt)
      fmt.LinkTo(enc)
      enc.LinkTo(mux)
      mux.LinkTo(snk)

    End If

  Else
    If $RecordingFormat = mp3 Then
      pl = New MediaPipeline
      src = New MediaControl(pl, "uridecodebin")
      src["uri"] = $StreamURL
      fmt = New MediaControl(pl, "audioconvert")
      enc = New MediaControl(pl, "lamemp3enc")
      enc["quality"] = 0
      enc["target"] = "bitrate"
      enc["bitrate"] = 128
      enc["cbr"] = True
      mux = New MediaControl(pl, "id3v2mux")
      snk = New MediaControl(pl, "filesink")
      snk["location"] = $TempFilePath
      src.LinkLaterTo(fmt)
      fmt.LinkTo(enc)
      enc.LinkTo(mux)
      mux.LinkTo(snk)
    Else If $RecordingFormat = aac Then
      pl = New MediaPipeline
      src = New MediaControl(pl, "uridecodebin")
      src["uri"] = $StreamURL
      fmt = New MediaControl(pl, "audioconvert")
      enc = New MediaControl(pl, "faac")
      enc["quality"] = 0
      enc["target"] = "bitrate"
      enc["bitrate"] = 128
      enc["cbr"] = True
      mux = New MediaControl(pl, "id3v2mux")
      snk = New MediaControl(pl, "filesink")
      snk["location"] = $TempFilePath
      src.LinkLaterTo(fmt)
      fmt.LinkTo(enc)
      enc.LinkTo(mux)
      mux.LinkTo(snk)

    Else If $RecordingFormat = ogg Then
      pl = New MediaPipeline
      src = New MediaControl(pl, "uridecodebin")
      src["uri"] = $StreamURL
      fmt = New MediaControl(pl, "audioconvert")
      enc = New MediaControl(pl, "vorbisenc")
      mux = New MediaControl(pl, "oggmux")
      snk = New MediaControl(pl, "filesink")
      snk["location"] = $TempFilePath
      src.LinkLaterTo(fmt)
      fmt.LinkTo(enc)
      enc.LinkTo(mux)
      mux.LinkTo(snk)
    Else If $RecordingFormat = wav Then
      pl = New MediaPipeline
      src = New MediaControl(pl, "uridecodebin")
      src["uri"] = $StreamURL
      fmt = New MediaControl(pl, "audioconvert")
      enc = New MediaControl(pl, "wavenc")
      snk = New MediaControl(pl, "filesink")
      snk["location"] = $TempFilePath
      src.LinkLaterTo(fmt)
      fmt.LinkTo(enc)
      enc.LinkTo(snk)
    End If
  End If

End

Private Function StreamURL_Read() As String

  Return $StreamURL

End

Private Sub StreamURL_Write(Value As String)

  $StreamURL = Value

End

Private Function Devices_Read() As String[]

  Dim s As String

  Shell "pacmd list-sources | grep 'name:' | cut -d" & Chr$(34) & " " & Chr$(34) & " -f2" To s
  s = Replace(s, "<", "")
  s = Replace(s, ">", "")
  Return Split(Trim(s), gb.LF)

End

Private Function Base_Read() As String

  Return $Base

End

Private Sub Base_Write(Value As String)

  $Base = Value

End


More information about the User mailing list