Pular para conteúdo

api

Controle de rótulos no Audacity via mod-script-pipe.

PyControlAudacity-cli é um script de linha de comando que cria rótulos em tempo de execução no Audacity por meio da interface mod-script-pipe. Seu uso é justificado em conjunto com uma instância do Audacity. Requer: Python 3 ou superior; Audacity 2.5.4 ou superior.

====================== Command Line Interface ======================

uso: PyControlAudacity-cli [--rotulo TEXT] [--sobreposicao {0, 5}] [--help] [--version] [--docs]

Argumentos

--rotulo: string, opcional
    string que será usada na criação do rótulo
--sobreposicao: int, opcional
    define o valor, em segundos, da sobreposição entre os rótulos [0 ou 5] (padrão: 5)
--help: opcional
    exibe a ajuda e sai
--version: opcional
    exibe a versão do programa e sai (default: 10)
--docs: opcional
    exibe esse documentação e sai

Copyright 2025 by dUnIO Lançada sob os termos da GNU General Public License versão 3: https://www.gnu.org/licenses/gpl-3.0.en.html /

carimbar(listaderotulos)

Função executada após interrupção da gravação Audacity, para organizar os rótulos registrados durante a execução do script.

Parameters:

Name Type Description Default
listaderotulos list

Uma ista contendo os rótulos registrados durante a execução

required
Source code in pycontrolaudacity_cli/PyControlAudacity-cli.py
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
def carimbar(listaderotulos: list):
    """
    Função executada após interrupção da gravação Audacity, para organizar os rótulos
    registrados durante a execução do script.

    Parameters:
        listaderotulos: Uma ista contendo os rótulos registrados durante a execução
    """
    # Recuperar informações do Audacity sobre o áudio gravado
    meu_json = do_command('GetInfo: Type=Clips Format=JSON')

    # Tratamento e limpeza das informações recuperadas do Audacity
    meu_json_str = meu_json.replace('BatchCommand finished: OK', '')
    str_temp = meu_json_str.replace('[', '')
    str_temp = str_temp.replace(']', '')
    meu_dicionario = dict(json.loads(str_temp))

    # Registra o tempo total do áudio informado pelo Audacity
    duracaodoaudio = meu_dicionario['end']

    # Registrar a data de hoje em string
    hoje_obj = datetime.now()
    hoje_str = hoje_obj.strftime('%Y-%m-%d')

    if duracaodoaudio < primeirorotulo or len(listaderotulos) == 0:
        rotulo_str = f"{ROTULO}-[{hoje_str}_{gravacao_hora_inicio_str.replace(':', '_')}]-000"

        cmd_audacity = f'SetLabel: Label=0 Text={rotulo_str} Start=0'
        if duracaodoaudio < primeirorotulo: cmd_audacity = f'{cmd_audacity} End={duracaodoaudio}'
        else: cmd_audacity = f'{cmd_audacity} End={primeirorotulo}'

        do_command('AddLabel')
        do_command(cmd_audacity)
        return

    if len(listaderotulos) == 1:
        # Mover cursor para o final da trilha
        do_command('CursTrackEnd:')
        # Criar o último rótulo
        do_command('AddLabel')
        rotulo_str = f"{ROTULO}-[{hoje_str}_{gravacao_hora_inicio_str.replace(':', '_')}]-000"
        cmd_audacity = f'SetLabel: Label=0 Text={rotulo_str} Start=0 End={primeirorotulo}'
        do_command(cmd_audacity)

        str_t1 = listaderotulos[0]
        hora_t1 = datetime.strptime(str_t1, '%H:%M:%S')
        t1 = timedelta(
            hours=hora_t1.hour, minutes=hora_t1.minute, seconds=hora_t1.second
        )
        t2 = timedelta(seconds=INTERVALO)
        t3 = t1 + t2
        rotulo_str = f'{ROTULO}-[{hoje_str}_{t3}]-001'.replace(':', '_')

        if primeirorotulo <= SOBREPOSICAO: cmd_audacity = f'SetLabel: Label=1 Text={rotulo_str} Start={primeirorotulo} End={duracaodoaudio}'
        else: cmd_audacity = f'SetLabel: Label=1 Text={rotulo_str} Start={primeirorotulo-SOBREPOSICAO} End={duracaodoaudio}'

        do_command(cmd_audacity)
        return

    # Lista que contém comandos para alterar os rótulos no Audacity
    listaaudacity = []
    # Lista para criar arquivo de rótulos exportados
    listaexportacao = []
    controle = 0
    for i in range(len(listaderotulos)):
        controle += 1
        rotulo_str = f"{ROTULO}-[{hoje_str}_{str(listaderotulos[i]).replace(':', '_')}]-{i:003}"
        if i == 0:
            cmd_audacity = f"SetLabel: Label=0 Text={rotulo_str} Start=0 End={primeirorotulo}"
            cmd_exportar = f'0.000000\t{primeirorotulo:,.6f}\t{rotulo_str}'
        else:
            ptr_inicio = primeirorotulo + INTERVALO * (i - 1)
            ptr_fim = min(ptr_inicio + INTERVALO, duracaodoaudio)
            if primeirorotulo <= SOBREPOSICAO:
                # Não descontar valor da sobreposição, pois a sobreposição é maior que o primeiro rótulo
                cmd_audacity = f"SetLabel: Label={i} Text={rotulo_str} Start={ptr_inicio} End={ptr_fim}"
                cmd_exportar = f"{ptr_inicio:,.6f}\t{ptr_fim:,.6f}\t{rotulo_str.replace(':', '_')}"
            else:
                cmd_audacity = f"SetLabel: Label={i} Text={rotulo_str} Start={ptr_inicio-SOBREPOSICAO} End={ptr_fim}"
                cmd_exportar = f"{ptr_inicio-SOBREPOSICAO:,.6f}\t{ptr_fim:,.6f}\t{rotulo_str.replace(':', '_')}"
        listaaudacity.append(cmd_audacity)
        listaexportacao.append(cmd_exportar)
        # Enviar comando ao Audacity para modificar o rótulo
        do_command(cmd_audacity)

    str_t1 = listaderotulos[len(listaderotulos) - 1]
    hora_t1 = datetime.strptime(str_t1, '%H:%M:%S')
    t1 = timedelta(
        hours=hora_t1.hour, minutes=hora_t1.minute, seconds=hora_t1.second
    )
    t2 = timedelta(seconds=INTERVALO)
    t3 = t1 + t2

    # Calcular o último rótulo, que não chegou a fechar em 5 minutos
    ult_sobreposicao = ptr_fim - SOBREPOSICAO
    # Preparar string do comando que será enviado ao Audacity
    rotulo_str = f'{ROTULO}-[{hoje_str}_{t3}]-{len(listaderotulos):003}'

    # Envia comando ao Audacity para selecionar o trecho do áudio para o último rótulo
    do_command(f'Select: Start={ult_sobreposicao} End={duracaodoaudio}')
    # Envia comando ao Audacity para criar o último rótulo
    do_command('AddLabel')
    # Envia comando ao Audacity para modificar o rótulo adicionado
    do_command(
        f"SetLabel: Label={len(listaderotulos)} Text={rotulo_str.replace(':', '_')}"
    )
    # Envia comando ao Audacity para não selecionar nenhum trecho do áudio gravado
    do_command('SelectNone')

    # Registro dos comando enviados ao Audacity em Log para controle posterior e tratamento de erros
    cmd_audacity = f"SetLabel: Label={len(listaderotulos)} Text={rotulo_str.replace(':', '_')} Start={ult_sobreposicao} End={duracaodoaudio}"
    cmd_exportar = f"{ult_sobreposicao:,.6f}\t{duracaodoaudio:,.6f}\t{rotulo_str.replace(':', '_')}"
    listaaudacity.append(cmd_audacity)
    listaexportacao.append(cmd_exportar)
    logfile = f"{os.path.dirname(__file__)}/PyControl-{hoje_str}_{gravacao_hora_inicio_str.replace(':', '_')}.txt"
    with open(logfile, 'w', encoding='utf-8') as arquivo:
        for tarefa in listaexportacao:
            arquivo.write(tarefa)
            arquivo.write('\n')
    arquivo.close
    return

do_command(command)

Envia um comando ao Audacity e retorna a resposta.

Parameters:

Name Type Description Default
command str

Comando a ser executado no Audacity

required

Returns:

Type Description
str

Resultado da execução do comando no Audacity

Source code in pycontrolaudacity_cli/PyControlAudacity-cli.py
189
190
191
192
193
194
195
196
197
198
199
200
201
def do_command(command: str) -> str:
    """
    Envia um comando ao Audacity e retorna a resposta.

    Parameters:
        command: Comando a ser executado no Audacity

    Returns:
        Resultado da execução do comando no Audacity
    """
    send_command(command)
    response = get_response()
    return response

get_response()

Resposta do Audacity ao comando executado.

Source code in pycontrolaudacity_cli/PyControlAudacity-cli.py
176
177
178
179
180
181
182
183
184
185
186
def get_response() -> str:
    """Resposta do Audacity ao comando executado."""
    global PIPELEITURA
    result = ''
    line = ''
    while True:
        result += line
        line = PIPELEITURA.readline()
        if line == '\n' and len(result) > 0:
            break
    return result

rotuladora()

Calcula os rótulos e registra no Audacity

Source code in pycontrolaudacity_cli/PyControlAudacity-cli.py
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
def rotuladora():
    """Calcula os rótulos e registra no Audacity"""
    global totalderotulos, listadetimestamps
    global INTERVALO, SOBREPOSICAO

    ponteiro1 = time.time()
    acumulador = 0
    while thread1.is_alive():
        ponteiro2 = time.time()
        if acumulador == 0:     # Registrar o primeiro rótulo no Audacity
            if ponteiro2 - ponteiro1 >= primeirorotulo:
                tmp = datetime.now().time().strftime('%H:%M:%S')
                listadetimestamps.append(gravacao_hora_inicio_str)
                # Registra o rótulo no Audacity
                do_command('AddLabelPlaying')
                ponteiro1 = ponteiro2
                acumulador += 1
                # Incrementa o total de rótulos registrados (variável global do script)
                totalderotulos += 1
                pass
        else:                   # Registrar demais rótulos no Audacity, a cada INTERVALO segundos
            if ponteiro2 - ponteiro1 >= INTERVALO:
                listadetimestamps.append(tmp)
                tmp = datetime.now().time().strftime('%H:%M:%S')
                # Registra o rótulo no Audacity
                do_command('AddLabelPlaying')
                ponteiro1 = ponteiro2
                acumulador += 1
                # Incrementa o total de rótulos registrados (variável global do script)
                totalderotulos += 1
                continue
            else:
                pass
    return

send_command(command)

Envia um comando ao Audacity.

Source code in pycontrolaudacity_cli/PyControlAudacity-cli.py
169
170
171
172
173
def send_command(command):
    """Envia um comando ao Audacity."""
    global PIPEESCRITA
    PIPEESCRITA.write(command + EOL)
    PIPEESCRITA.flush()

ui()

Controla a interrupção do script e da gravação no Audacity

Source code in pycontrolaudacity_cli/PyControlAudacity-cli.py
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
def ui():
    """Controla a interrupção do script e da gravação no Audacity"""
    global gravacao_hora_final_obj, gravacao_hora_final_str
    while True:
        mensagem = input(
            "Para interromper o script, tecle 'S' e pressione [ ENTER ]: "
        )
        if mensagem.lower() == 's':
            # Parar a gravação no Audacity
            do_command('Stop')

            # Registrar o final da gravação na variável global 'gravacao_hora_final_obj'; e
            # Converter o final da gravação em string para usar na interface com usuário
            gravacao_hora_final_obj = datetime.now().time()
            gravacao_hora_final_str = gravacao_hora_final_obj.strftime(
                '%H:%M:%S'
            )

            # Inserir o timestamp nos rótulos que foram criados no Audacity
            carimbar(listadetimestamps)
            break
        else:
            # Usuário pressionou qualquer tecla diferente de 's' no terminal
            # Desconsiderar comando e continuar executando modelo para criar rótulos no áudio
            pass
    return