Como posso restaurar registros de data e hora de arquivos de gravações de vídeo usando os metadados incorporados?

6

Estou procurando um comando que leia os metadados de um arquivo " *.mp4 " e toque no timestamp do arquivo com o horário de criação do vídeo. O comando deve ser somente leitura em relação ao conteúdo do arquivo, ou seja, fazer o hashing do arquivo antes e depois deve render o mesmo resultado.

Situação: cometi o erro de mover imagens e vídeos do armazenamento interno do meu telefone para um cartão SD usando a ferramenta de estoque do Android para fazer isso ("Configurações" → "Armazenamento" → "Transferir dados para o cartão SD"). Infelizmente, isso colidiu com os timestamps de todos os arquivos e também com diretórios diferentes de DCIM/ (fotos e vídeos também foram movidos dos diretórios Download/ , image/ , Pictures/ e video/ ) . Em retrospectiva parece bobo que eu usei essa ferramenta (eu normalmente usaria Ghost Commander ), mas apareceu como uma notificação quando estava com pouco espaço e parecia tão fácil. Agora estou tentando juntar os timestamps de várias fotos e vídeos.

Estou efetivamente procurando um vídeo equivalente ao seguinte comando , que usei para classificar o imagens em DCIM/100ANDRO/ :

exiv2 -T mv *.JPG

Analisei algumas documentação do FFmpeg , mas não vejo menção a comandos somente leitura ou impressão de timestamps.

(Infelizmente, para minha situação, essa abordagem não oferece uma solução para os arquivos que eu não criei, como aqueles em Download/ , para os quais quero aparecer na coleção de mídia em ordem cronológica de quando os obtive .)

    
por James Haigh 24.02.2014 / 03:44

3 respostas

8

Obrigado a Warren por me informar sobre o comando mediainfo em sua resposta parcial.

Consegui construir um comando que conseguiu a restauração de timestamps. Ele percorre os arquivos aplicáveis e, para cada arquivo, mediainfo lê os metadados, grep e sed selecionam e formatam o registro de data e hora, e touch o aplica.

for file in *.mp4; do touch -t "$(mediainfo "$file" | grep -m 1 'Tagged date' | sed -r 's/.*([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2}).*/./')" "$file"; done

A parte de "selecionar e formatar" poderia, sem dúvida, ser muito mais curta / melhor; parece complicado para mim, mas eu não sou fluente com regexs. No entanto, o comando funcionou perfeitamente. Acho que citei tudo corretamente, então deve funcionar com qualquer nome de arquivo. Pode não funcionar se mediainfo apresentar um formato diferente, mas é facilmente adaptável.

Por exemplo, aqui está uma regex que corresponde corretamente ao formato de saída dos meus arquivos *.mp4 , como UTC 2013-11-15 11:36:06 , e, adicionalmente, ao formato do exemplo de Warren de 2014-2-23T09:00:00Z de my.mov :

's/-/-0/g; s/.*([0-9]{4})-0?([0-9]{2})-0?([0-9]{2})[T ]([0-9]{2}):([0-9]{2}):([0-9]{2}).*/./'

E além de mediainfo que eu tive que instalar manualmente devido a ele não estar nos repositórios da minha distro (embora pareça que os novos lançamentos agora o empacotam), ele deve ser razoavelmente portátil e útil para os outros se encontrarem um problema semelhante.

Nota: lembre-se de verificar os fusos horários. De acordo com as páginas GNU info , touch , date e outros utilitários GNU usam a variável de ambiente TZ se configuradas e as "regras padrão do sistema" caso contrário. Para ver o deslocamento do fuso horário que será usado, emita:

date +%:::z

Para alterá-lo, defina a variável de ambiente TZ :

export TZ="UTC0"

Se os carimbos de data / hora do vídeo estiverem corretos e estiverem corretamente representados (ou seja, o valor de tempo para o fuso horário representar o ponto correto no tempo), certifique-se de que date +%:::z produza o deslocamento correspondente para o fuso horário do timestamp antes de executar touch -t sobre esses arquivos (como acima). Use stat para verificar os arquivos, pois mostra o deslocamento de tempo (como date +%:::z ).

    
por 24.02.2014 / 11:14
2

Você pode usar MediaInfo para isso:

$ mediainfo my.mov | grep 'Recorded date'
Recorded date                            : 2014-2-23T09:00:00Z

Começar desse formato de data para um comando touch deve ser uma pequena questão de programação. Pessoalmente, eu usaria o módulo Date::Manip do Perl para esse . Pode quase lidar com o formato acima; requer meses de 2 dígitos com preenchimento zero para entender esse formato de data específico. Corrigir isso requer apenas um regexp trivial, o que é fácil em Perl.

$ perl -M'Date::Manip' -e 'print ParseDate("2014-02-23T09:00:00Z")'
2014022302:00:00

O fato de imprimir mostra que está analisando. Se você eliminar o 0 , verá que ele não imprime nada, porque ParseDate() retorna undef .

    
por 24.02.2014 / 04:47
0

Siga os conselhos de James acima para MP4 e a maioria dos arquivos do QuickTime. Para arquivos AVI, mediainfo produzirá Mastered date , mas o formato é praticamente inalterável. Instale ffmpeg para obter ffprobe (também conhecido como avprobe ) e use:

for file in *.avi; do touch -t "$(ffprobe "$file" 2>&1 | grep -m 1 'creation_time' | sed -r 's/.*([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2}).*/./')" "$file"; done

Observe o mod antes da canalização para grep . Isso ocorre porque ffprobe usa stderr não stdout.

    
por 14.10.2015 / 08:24