A sugestão de Matt sobre quadros-chave, combinada com uma dica oportuna postada na lista de discussão do ffmpeg, me levou a uma solução, embora eu não tenha certeza se é a melhor solução.
Primeiro, tive que mover as opções -ss e -t no meu comando de extração para que elas aparecessem antes da opção -i. Isso faz com que a extração comece no próximo quadro-chave mais antigo. Então, digamos que eu use -ss 25 -t 15 para extrair de 0:25 a 0:40 no meu clipe, mas tenho quadros-chave a cada 10 segundos. Anteriormente, eu recebia uma amostra de 15 segundos, começando com 5 segundos de vídeo em branco. Agora vou pegar uma amostra de 20 segundos, rodando de 0:20 a 0:40, mas sem vídeo em branco. Em outras palavras, evito o vídeo em branco, mas perco a precisão da seleção do clipe.
Para resolver isso, tive que adicionar a opção -g ao meu comando de conversão para reformatar os quadros-chave. Eu usei -g 15 com -r 15 para fazer um quadro-chave a cada segundo. Isso permite que eu escolha locais de amostra para o segundo mais próximo, então -ss 25 -t 15 me dará o clipe de 15 segundos que eu pedi. Eu esperaria que os quadros-chave extras tornassem meu clipe completo maior, mas ele é apenas cerca de 2% maior em meus testes, e isso é um bom compromisso para o meu projeto.
Então, eu mudei meus dois comandos acima para:
ffmpeg -i uploaded.mov -f mp4 -vcodec libx264 -vpre medium -acodec libfaac -r 15 -g 15 -b 360k -ab 48k -ar 22050 -s 480x320 formatted.mp4
ffmpeg -ss 0 -t 30 -i formatted.mp4 -vcodec copy -acodec copy formatted_sample.mp4
E tudo parece bem. Se alguém tiver uma solução mais eficiente, poste e alterarei a resposta escolhida.