Kontext und Frage

Kontext und Frage

Kontext und Frage

Ich habe mit meinem Android-Telefon MotoG3 ein Video aufgenommen und das resultierende Video (möglicherweise aufgrund des Schüttelns des Telefons) wird gedreht, also vertikal, abgespielt, was ich nicht möchte. Das Video wurde in einem MP4-Container gespeichert.

Beim Überprüfen der aufgezeichneten Datei habe ich (unter Verwendung von ffprobeund mediainfo) festgestellt, dass sie ein Flag enthält, das angibt, dass der Videostream um 90 Grad gedreht ist, was die Drehung während der Wiedergabe des Videos erklärt. Hier ist die Ausgabe von ffprobe:

$ ffprobe -hide_banner ~/Pictures/2016/06/19/vid_20160619_170845475.mp4 
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/rbrito/Pictures/2016/06/19/vid_20160619_170845475.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2016-06-19 20:25:49
    com.android.version: 6.0
  Duration: 00:17:01.96, start: 0.000000, bitrate: 17134 kb/s
    Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 17000 kb/s, SAR 1:1 DAR 16:9, 29 fps, 29.42 tbr, 90k tbn, 180k tbc (default)
    Metadata:
      rotate          : 90
      creation_time   : 2016-06-19 20:25:49
      handler_name    : VideoHandle
      encoder         : MOTO
    Side data:
      displaymatrix: rotation of -90.00 degrees
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      creation_time   : 2016-06-19 20:25:49
      handler_name    : SoundHandle

Da dieses Video von einem seltenen Ereignis mit meinem Sohn stammt, möchte ich die Videodatei nur minimal ändern, vorzugsweise nur die Rotationsmetadaten entfernen und sonst nichts.

Leider verwenden wir Informationen ausAndere Antworthat nicht geholfen. Ich habe versucht:

ffmpeg -i ~/Pictures/2016/06/19/vid_20160619_170845475.mp4 -c copy -metadata:s:v:0 rotate=0 -an vid_20160619_170845475_unrotated.mp4

Andere Metadaten wie Datum etc. sind in der resultierenden Datei jedoch nicht vorhanden. Dies führt insbesondere bei Organizer-Programmen zu Verwirrungen, wenn diese die Dateien u.a. nach Datum anzeigen.

Gibt es eine Möglichkeit, die Eingabedaten minimal zu verändern (möglicherweise durch Remuxen), um sie möglichst nah an den Originaldaten zu halten? Insbesondere möchte ich die Datei nicht neu kodieren.

Alle unter Linux verfügbaren Tools werden bevorzugt.


Zusatzinformation

Da die vollständige Ausgabe von ffmpeg angefordert wurde, ist sie hier. Dies ist ein reines Debian-Testbenutzerland.

Nebenbei bemerkt beschwert sich ffmpeg über nicht übereinstimmende Bibliotheken, da es in Debian zweimal kompiliert wird, einmal ohne potenziell problematische Codecs und einmal mit einigen zusätzlichen Codecs. Ich verwende die Version mit zusätzlichen Codecs, aber ich nehme an, dass das keine Rolle spielt, da hier nur das Multiplexen verwendet wird.

Metadaten vor dem Remuxen

$ ffprobe  -hide_banner ~/Pictures/2016/06/19/vid_20160619_170845475.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/rbrito/Pictures/2016/06/19/vid_20160619_170845475.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2016-06-19 20:25:49
    com.android.version: 6.0
  Duration: 00:17:01.96, start: 0.000000, bitrate: 17134 kb/s
    Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 17000 kb/s, SAR 1:1 DAR 16:9, 29 fps, 29.42 tbr, 90k tbn, 180k tbc (default)
    Metadata:
      rotate          : 90
      creation_time   : 2016-06-19 20:25:49
      handler_name    : VideoHandle
      encoder         : MOTO
    Side data:
      displaymatrix: rotation of -90.00 degrees
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      creation_time   : 2016-06-19 20:25:49
      handler_name    : SoundHandle

Der Remuxing-Prozess

Beachten Sie hier, dass die Audio-Metadaten nicht kopiert werden (was ich aufgrund der -metadata:s:v:0Option erwartet hatte) und ffmpeg mir mitteilt, dass es die Video-Metadaten kopiert (ohne die Rotationseinstellung).

$ ffmpeg -hide_banner -i ~/Pictures/2016/06/19/vid_20160619_170845475.mp4 -c copy -metadata:s:v:0 rotate=0 -an vid_20160619_170845475_unrotated.mp4 
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/rbrito/Pictures/2016/06/19/vid_20160619_170845475.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2016-06-19 20:25:49
    com.android.version: 6.0
  Duration: 00:17:01.96, start: 0.000000, bitrate: 17134 kb/s
    Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 17000 kb/s, SAR 1:1 DAR 16:9, 29 fps, 29.42 tbr, 90k tbn, 180k tbc (default)
    Metadata:
      rotate          : 90
      creation_time   : 2016-06-19 20:25:49
      handler_name    : VideoHandle
      encoder         : MOTO
    Side data:
      displaymatrix: rotation of -90.00 degrees
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      creation_time   : 2016-06-19 20:25:49
      handler_name    : SoundHandle
Output #0, mp4, to 'vid_20160619_170845475_unrotated.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    com.android.version: 6.0
    encoder         : Lavf57.25.100
    Stream #0:0(eng): Video: h264 ([33][0][0][0] / 0x0021), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 17000 kb/s, 29 fps, 29.42 tbr, 90k tbn, 90k tbc (default)
    Metadata:
      encoder         : MOTO
      creation_time   : 2016-06-19 20:25:49
      handler_name    : VideoHandle
      rotate          : 0
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
frame=29640 fps=403 q=-1.0 Lsize= 2121038kB time=00:17:01.91 bitrate=17003.0kbits/s speed=13.9x    
video:2120800kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.011211%

Metadaten nach dem Remuxing

Beachten Sie hierbei, dass die Ausgabe keine Videometadaten enthält, sondern nur Metadaten auf Containerebene.

$ ffprobe -hide_banner vid_20160619_170845475_unrotated.mp4 
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'vid_20160619_170845475_unrotated.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf57.25.100
  Duration: 00:17:01.95, start: 0.000000, bitrate: 17002 kb/s
    Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 17000 kb/s, 29 fps, 29.42 tbr, 90k tbn, 180k tbc (default)
    Metadata:
      handler_name    : VideoHandler

Antwort1

FFmpeg überträgt standardmäßig nicht die meisten Benutzermetadaten, aber es überträgt Felder wie das Rotationstag.

Der folgende Befehl weist FFmpeg an, alle Metadaten zu übertragen, überschreibt dann jedoch den Rotations-Tag-Wert.

ffmpeg -i in.mp4 -c copy -map_metadata 0 -metadata:s:v:0 rotate=0 -an out.mp4

Antwort2

Führen Sie diesen Befehl aus:

ffmpeg -i oldfile.mp4 -codec copy -metadata title="" -metadata album="" -metadata year="" -metadata container="" -metadata artist="" -metadata comment="" newfile.mp4

Durch die Verwendung von "" in jedem Metadatentyp werden alte Metadaten geleert und ffmpeg kopiert dann die gesamte Datei mit gelöschten Metadaten in eine neue Datei.

Um Duplikate zu vermeiden, müssen Sie nach dem Erstellen einer neuen Datei die alte Datei löschen.

Antwort3

  • Installieren Sie die Mutagen-Python-Bibliothek:

    python3.6 -m pip install --user mutagen
    

    oder:

    python2.7 -m pip install --user mutagen
    

    Mutagen ist ein Python-Modul zur Verarbeitung von Audio-Metadaten.

  • Speichern Sie den folgenden Inhalt unter „, metadata_cleaner.pySie können ihm aber einen beliebigen Namen geben.“

  • Ändern Sie die VIDEO_FOLDER = 'your_full_path_for_your_videos_folder'Variable.

  • Ändern Sie die Attribute, die Sie überschreiben möchten, zwischen den Zeilen mit dem Text „Ihre Änderungen“.

  • Laufen Sie python metadata_cleaner.pyüberall hin.

Hier ist das Skript:

import os
from mutagen.mp4 import MP4
## Can import MP3 as well if you want to modify MP3 files

## Folder full path to the files you want to modify:

FILES_FOLDER = "/media/removable/64GB-Micro/FilesToClean"

def get_all_files(path):
    """Returns all the files in the path as a list
    """
    return os.listdir(path)

def clean_metadata(videos_dir, files):
    """
    Receives two variables videos_dir (full file folder path) and files (list)
    Iterates over all the files in the directory and creates full paths for 
    every file using the videos_dir path and os.path.join function.
    """
    for file_name in files:
        file_path = os.path.join(videos_dir, file_name)

        ## create MP4 video_file instance

        video_file = MP4(file_path)

        ## This line will print out all key-value for the video_file-s:
        ## Useful if you don't know which attributes you want to modify yet

        print(video_file)

        ## In this example I wanted to clean the ART, aArt = Artist metadata
        ## and nam = Song Name metadata
        ## These prints will show artists and titles for each file before clean
        ## -------------------------- Your changes ---------------------------
        print("file_name: {}".format(file_name))
        print("Old ART: {}".format(video_file.get('\xa9ART', "Key not found")))
        print("Old aArt: {}".format(video_file.get('aART', "Key not found")))
        print("Old nam: {}".format(video_file.get('\xa9nam', "Key not found")))

        ## clean artist and name
        ## This part will overwrite the artist and song name attributes

        video_file['\xa9ART'] = ''
        video_file['aART'] = ''
        video_file['\xa9nam'] = ''
        ## -------------------------- Your changes ---------------------------
        ## save new metadata

        video_file.save()

        ## show video_file artist and title after clean
        ## Just to see if our actions were successful print out song metadata
        ## again after the changes

        print("New ART: {}".format(video_file.get('\xa9ART', "Key not found")))
        print("New aArt: {}".format(video_file.get('aART', "Key not found")))
        print("New nam: {}".format(video_file.get('\xa9nam', "Key not found")))


if __name__ == '__main__':
    ## load all the files into files variable as a list

    files = get_all_files(FILES_FOLDER)

    ## run clean_metadata function to clean all the files in the VIDEO_FOLDER
    ## path
    clean_metadata(videos_dir=FILES_FOLDER, files=files)

verwandte Informationen