재생이 시작될 때 오디오가 지연되지 않도록 Fedora 35에서 WirePlumber를 사용하여 유휴 상태에서 오디오 수신기가 일시 중지되는 것을 어떻게 비활성화합니까?

재생이 시작될 때 오디오가 지연되지 않도록 Fedora 35에서 WirePlumber를 사용하여 유휴 상태에서 오디오 수신기가 일시 중지되는 것을 어떻게 비활성화합니까?

Fedora 35에서는 WirePlumber가 파이프라인-미디어-세션을 오디오 세션 관리자로 대체합니다. Linux에 내장된 많은 사운드 카드의 오디오에는 3초 동안 아무것도 재생되지 않으면 오디오 수신기가 일시 중지되는 매우 성가신 문제가 있습니다. 3초 후에 재생이 다시 시작되면 오디오가 지연되거나 튀어나옵니다. 이 기본 동작을 어떻게 수정할 수 있나요?

답변1

관련 구성 파일은 이지만 /usr/share/wireplumber/main.lua.d/50-alsa-config.lua시스템 버전을 편집하지 마십시오!

/etc/wireplumber/main.lua.d/이를 (전역 구성) 또는 (사용자 구성) 에 복사 ~/.config/wireplumber/main.lua.d/하고 필요한 사항을 변경해야 합니다.

가장 쉬운 방법은 모든 사용자 계정에 적용되도록 이를 전역 구성 위치에 복사하는 것입니다.

sudo cp -a /usr/share/wireplumber/main.lua.d/50-alsa-config.lua /etc/wireplumber/main.lua.d/50-alsa-config.lua
sudo nano /etc/wireplumber/main.lua.d/50-alsa-config.lua

apply_properties그런 다음 파일 하단의 해당 섹션까지 아래로 스크롤하고 거기에 한 줄을 추가해야 합니다 .

["session.suspend-timeout-seconds"] = 0

나는 몇 가지를 더 변경하고 내 개인 하드웨어에 맞게 사용자 정의했습니다. 참조용 구성은 다음과 같습니다. 그러나 이 구성은 정확한 장치에서만 작동합니다. 실제로 자동 일시 중단을 비활성화하려면 위의 줄만 필요합니다. 이것을 자신의 기본 구성에 추가하십시오.내 구성을 복사하지 마세요.내가 변경한 다른 사항은 관련이 없습니다.

alsa_monitor.properties = {
  ["alsa.jack-device"] = true,
  ["alsa.reserve"] = true,
  ["alsa.midi.monitoring"] = true
}

alsa_monitor.rules = {
{
    matches = {
      {
        { "device.name", "matches", "alsa_card.*" }
      }
    },
    apply_properties = {
      ["api.alsa.use-acp"] = true,
      ["api.acp.auto-profile"] = false,
      ["api.acp.auto-port"] = false
    }
  },
  {
    matches = {
      {
        { "node.name", "matches", "alsa_output.pci-0000_0c_00.4.iec958-ac3-surround-51" }
      }
    },
    apply_properties = {
      ["api.alsa.period-size"] = 128,
      ["api.alsa.headroom"] = 2048,
      ["session.suspend-timeout-seconds"] = 0
    }
  },
  { 
    matches = {
      {
        { "node.name", "matches", "alsa_input.usb-BEHRINGER_UMC202HD_192k-00.analog-mono" }
      }
    },
    apply_properties = {
      ["api.alsa.period-size"] = 128
    }
  }
}

일시 중지/절전 동작을 방지 하려면 이 session.suspend-timeout-seconds속성을 설정하십시오. 0WirePlumber의 소스 코드에 표시된 것처럼 동작을 완전히 비활성화합니다.

변경 사항을 적용하려면 WirePlumber를 다시 시작해야 합니다.

systemctl --user restart wireplumber

답변2

session.suspend-timeout-secondsWirePlumber 없이 PipeWire를 실행하고 파이프라인-미디어-세션을 사용하는 시스템에서는 일반적으로 하단 부분을 0 으로 변경하여 문제를 해결할 수 있습니다 /etc/pipewire/media-session.d/alsa-monitor.conf. 그러나 이 디렉터리나 세션 모니터 구성 파일은 Fedora 35 설치에서 찾을 수 없습니다. 실제로 수신기가 3초 동안 정지되는 것을 방지하는 방법을 보여주는 문서가 없으므로 이 문제를 직접 알아내야 했습니다. 대신 WirePlumber 스크립트 디렉터리에서 Lua 스크립트를 수정해야 합니다. 해당 항목 으로 이동하여 /usr/share/wireplumber/scripts/백업 복사본을 만듭니다 suspend-node.lua. 그런 다음 sudo 권한이 있는 텍스트 편집기나 터미널에서 열고 suspend-node.lua파일이 다음과 같도록 수신기 시간 초과 및 수신기 일시 중단을 담당하는 코드 블록을 주석 처리합니다.

-- WirePlumber
--
-- Copyright © 2021 Collabora Ltd.
--    @author George Kiagiadakis <[email protected]>
--
-- SPDX-License-Identifier: MIT

om = ObjectManager {
  Interest { type = "node",
    Constraint { "media.class", "matches", "Audio/*" }
  },
  Interest { type = "node",
    Constraint { "media.class", "matches", "Video/*" }
  },
}

sources = {}

om:connect("object-added", function (om, node)
  node:connect("state-changed", function (node, old_state, cur_state)
    -- Always clear the current source if any
    local id = node["bound-id"]
    if sources[id] then
      sources[id]:destroy()
      sources[id] = nil
    end

--    -- Add a timeout source if idle for at least 3 seconds
--    if cur_state == "idle" then
--      -- honor "session.suspend-timeout-seconds" if specified
--      local timeout =
--          tonumber(node.properties["session.suspend-timeout-seconds"]) or 3

--      if timeout == 0 then
--        return
--      end

--      -- add idle timeout; multiply by 1000, timeout_add() expects ms
--      sources[id] = Core.timeout_add(timeout * 1000, function()
--        -- Suspend the node
--        Log.info(node, "was idle for a while; suspending ...")
--        node:send_command("Suspend")

--        -- Unref the source
--        sources[id] = nil

--        -- false (== G_SOURCE_REMOVE) destroys the source so that this
--        -- function does not get fired again after 3 seconds
--        return false
--      end)
--    end

  end)
end)

om:activate()

전체 블록을 주석 처리하는 것보다 더 나은 방법이 있을 수 있지만 적어도 이 방법을 사용하면 수신자의 상태가 유휴 상태인지 확인하는 데 처리 시간을 낭비하지 않습니다. 이제 수신기가 몇 초 동안 유휴 상태였다가 음악 및 비디오 재생을 다시 시작할 때 성가신 오디오 지연이나 팝 현상이 발생하지 않습니다. 이것이 Fedora 35에서 WirePlumber를 사용하는 모든 사람에게 도움이 되기를 바랍니다.

답변3

나는 인터넷 검색과 여기에 설명된 작업을 수행하는 데 많은 시간을 보냈습니다.

전체 알고리즘은 여기에 남겨두겠습니다(Ubuntu 23.04에서는 매력적으로 작동합니다).

  1. 구성을 전역 범위로 이동하고 해당 session.suspend-timeout-seconds매개변수를 변경합니다.

    # Main config
     sudo mkdir -p /etc/wireplumber/main.lua.d
     sudo cp -a /usr/share/wireplumber/main.lua.d/50-alsa-config.lua /etc/wireplumber/main.lua.d/50-alsa-config.lua
    
     # Bluetooth config
     sudo mkdir -p /etc/wireplumber/bluetooth.lua.d/
     sudo cp -a /usr/share/wireplumber/bluetooth.lua.d/50-bluez-config.lua /etc/wireplumber/bluetooth.lua.d/50-bluez-config.lua
    
     # Change the needed settings in both config files
     # Pay attention to `--` in the beggining. It's a line comment in Lua. And we must remove it
     sudo sed -i 's/--\["session.suspend-timeout-seconds"\] = 5/\["session.suspend-timeout-seconds"\] = 0/g' /etc/wireplumber/main.lua.d/50-alsa-config.lua
     sudo sed -i 's/--\["session.suspend-timeout-seconds"\] = 5/\["session.suspend-timeout-seconds"\] = 0/g' /etc/wireplumber/bluetooth.lua.d/50-bluez-config.lua
    
  2. 그런 다음 서비스를 다시 로드합니다.

    systemctl --user restart pipewire wireplumber
    
  3. 그런 다음 오디오를 재생 및 중지할 때 이 명령을 사용하여 모든 오디오 장치의 상태를 테스트하고 상태 변경을 관찰할 수 있습니다.

    watch -cd -n .1 pactl list short sinks
    

    상태가 표시됩니다.

    • RUNNING — 장치가 현재 재생 중이거나 재생된 지 10초 미만입니다.
    • IDLE — 장치가 재생 중이 아니지만 즉시 재생할 준비가 되어 있습니다(필요한 것!)
    • 일시중지 - 이 상태에서는 기기의 절전 모드 해제가 지연됩니다(필수 아님).

    세션에서 첫 번째 재생 후에 SUSPENDED 상태가 발생하면 안 됩니다.

축하해요! 이제 오디오가 원활하게 재생됩니다.

답변4

관련 구성 파일은 /usr/share/wireplumber/main.lua.d/50-alsa-config.lua이지만 시스템 버전을 편집하지 마십시오.

이 해결 방법은 Bluetooth 장치에서는 작동하지 않습니다. 작동하게 하려면 블루투스 파일을 복사하고 속성을 변경하세요 session.suspend-timeout-seconds.

sudo cp -a /usr/share/wireplumber/bluetooth.lua.d/50-bluez-config.lua /etc/wireplumber/bluetooth.lua.d/50-bluez-config.lua

sudo vi /etc/wireplumber/bluetooth.lua.d/50-bluez-config.lua

50-bluez-config.lua:

apply_properties = {
  --["node.nick"] = "My Node",
  --["priority.driver"] = 100,
  --["priority.session"] = 100,
  --["node.pause-on-idle"] = false,
  --["resample.quality"] = 4,
  --["channelmix.normalize"] = false,
  --["channelmix.mix-lfe"] = false,
  ["session.suspend-timeout-seconds"] = 0,  -- 0 disables suspend
  --["monitor.channel-volumes"] = false,

  -- Media source role, "input" or "playback"
  -- Defaults to "playback", playing stream to speakers
  -- Set to "input" to use as an input for apps
  --["bluez5.media-source-role"] = "input",
},

관련 정보