Como passar um valor que deve estar entre aspas para um comando?

1

Estou tentando criar um script que use o ffmpeg para gravar a tela e o áudio. O usuário poderá escolher o que será gravado: apenas a tela, apenas o microfone, somente os alto-falantes ou combinações desses.

Estou lutando para fazer o trabalho de gravação de som. Inicialmente tentei com Alsa, mas depois não consegui ouvir nada enquanto estava sendo gravado. Então eu tentei com Pulseaudio, mas o resultado foi ruim. Agora eu tentei com o OpenAL e o resultado é muito bom. No entanto, suas opções têm espaços e não consigo fazer o script funcionar de maneira confiável:

As opções do OpenAL são:

[openal @ 0x55c6aa3b77a0] List of OpenAL capture devices on this system:
[openal @ 0x55c6aa3b77a0]   Áudio interno Estéreo analógico
[openal @ 0x55c6aa3b77a0]   Monitor of Áudio interno Estéreo analógico

A linha de comando tem diferentes variáveis, dependendo das opções do usuário e do tamanho da tela, sendo:

env PULSE_LATENCY_MSEC=5 ffmpeg -vsync passthrough \
-vaapi_device /dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi \
${monitorsom} "${openal}" ${micro} "${microal}" ${complexo}   \
-thread_queue_size 4096 -framerate 30  \
-f x11grab -s "$(xdpyinfo  | grep -oP 'dimensions:\s+\K\S+')" -i :0.0  \
-acodec libfdk_aac -b:a 192k \
-vf 'format=nv12,hwupload' -vcodec h264_vaapi \
-f flv "${nome}"

O grande problema com essa abordagem é que as variáveis monitora , aberta , micro , microal e < strong> complexo pode estar vazio. Não há nenhum problema com o monitorsom , micro e complexo , o comando resultante está bem. No entanto, se openal ou microal estiverem vazios, o comando ffmpeg falhará. Se nenhuma opção for escolhida (sem som), o comando passado é:

 env PULSE_LATENCY_MSEC=5 ffmpeg -vsync passthrough -vaapi_device /dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi '' '' -thread_queue_size 4096 -framerate 30 -f x11grab -s 1366x768 -i :0.0 -acodec libfdk_aac -b:a 192k -vf format=nv12,hwupload -vcodec h264_vaapi -f flv TEST002.flv

Tem as aspas que devem ser usadas quando há uma opção, mas como estão vazias, o comando falha.

Se eu tentar uma abordagem diferente, alterando as partes variáveis para (sem aspas):

${monitorsom} ${openal} ${micro} ${microal} ${complexo}   \

Funciona quando está vazio, mas falha quando existe uma opção devido aos espaços. Eu tentei a seguinte abordagem para passar a variável com as citações necessárias:

openal=' "Monitor of Áudio interno Estéreo analógico" '

Aspas simples são adicionadas no meio do valor da variável, resultando em:

'"Monitor' of Áudio interno Estéreo 'analógico"'

Consequentemente, falhando.

Se eu tentar usar:

openal="  'Monitor of Áudio interno Estéreo analógico' " 

Isso resulta em:

''\''Monitor' of Áudio interno Estéreo 'analógico'\'''

Falha.

Existe uma maneira de passar a variável com as cotações necessárias? Eu gostaria de passar:

"Monitor of Áudio interno Estéreo analógico"

ou

'Monitor of Áudio interno Estéreo analógico'

Mas ele precisa aceitar valores sem aspas também. Por isso, acredito que eu deveria ser capaz de definir os valores das variáveis com aspas quando aspas são necessárias e nenhuma cotação se elas não são necessárias ou causará erros.

Obrigado.

    
por FurretUber 22.06.2017 / 20:58

1 resposta

2

Se o problema for argumentos vazios causando problemas, considere construir a linha de comando usando arrays, para que você possa filtrar as variáveis vazias:

opts=()
add_opt() {
    for i; do [[ -n "$i" ]] && ops+=("$i"); done
}
add_opt "${monitorsom}" "${openal}" "${micro}" "${microal}" "${complexo}"

Então:

env PULSE_LATENCY_MSEC=5 ffmpeg -vsync passthrough \
-vaapi_device /dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi \
"${opts[@]}"   \
-thread_queue_size 4096 -framerate 30  \
-f x11grab -s "$(xdpyinfo  | grep -oP 'dimensions:\s+\K\S+')" -i :0.0  \
-acodec libfdk_aac -b:a 192k \
-vf 'format=nv12,hwupload' -vcodec h264_vaapi \
-f flv "${nome}"

Se um opts estiver vazio, "${opts[@]}" se expande para nada e já filtramos as variáveis vazias.

(Eu vou em frente e coloco todas as opções na matriz. Quando eu tenho linhas de comando muito longas, eu costumo fazer:

opts=(
"opt1"
"opt2"
...
)
cmd "${opts[@]}"

O que facilita o acompanhamento das opções para mim.

    
por 22.06.2017 / 21:08