Давайте представим, что к вам попал некий файл: изображение, видео, а может быть аудиофайл, и вам нужно узнать о данном файле чуть больше информации чем отображается в свойствах файла. Если она там есть. Ведь современные камеры, смартфоны и прочее фото и видео оборудование добавляет их в файл в автоматическом режиме. И если файл не обработан программами, которые могут их затереть, то из таких метаданных, иногда, можно получить много разнообразной информации. В этом вам могут помочь специализированные программы, а можно воспользоваться небольшим скриптом на Python и получить необходимую информацию. Давайте создадим скрипт, который будет получать метаданные из фото, видео и аудио файлов.
Что понадобиться?
Для работы с изображениями установим библиотеку Pillow. Именно с ее помощью мы будем получать метаданные, если они, конечно же есть. А также установим библиотеку ffmpeg, которая работает с очень большим количеством форматов как аудио, так и видео. Причем, извлекает метаданные из фото (правда не все). Пишем в терминале команду:
После того, как все библиотеки будут установлены, импортируем нужные модули в скрипт.
Давайте приступим к созданию скрипта.
Извлекаем метаданные из файлов JPG
Создадим функцию для извлечения метаданных из изображения. Я назвал ее image_metadata(path_f). На входе она принимает только один параметр, а именно путь к файлу изображения. Затем с помощью модуля Image библиотеки Pillow откроем файл. Создадим небольшой словарь, в который добавим базовые данные о фото, такие как имя, разрешение, ширина, высота и прочие. Эти данные будут выводиться пользователю в том случае, если метеданных в фото не оказалось или они не были прочитаны.
Теперь, если данные exif были прочитаны и не было вызвано исключение, формируем словарь из полученных значений, к которому добавим в качестве ключа название тега. Для этого будем использовать параметр ExifTags.TAGS. Если вы распечатаете данный параметр, на выходе получите словарь с тегами, которые могут содержаться в изображении.
После того, как словарь будет сформирован, нужно вывести полученные значения пользователю на экран. Пробегаемся в цикле по словарю exif. Здесь, если мы получаем значение тега «GPSInfo», печатаем данные немного по другому, так как за данным тегом есть еще словарь со значениями широты, долготы, направления и прочие параметры. Для наших целей достаточно будет получить значение широты и долготы. Поэтому указываем значения json, где они содержаться, для вывода на экран.
Также, некоторые значения в json представлены в байтах, а потому из надо декодировать. Но, если мы будем декодировать все значения, то на экран ничего не выведется. Поэтому делаем проверку, является ли данный параметр байтами. Если да, декодируем и выводим уже декодированное значение.
Как вы помните, в изображении тегов может и не содержаться. Поэтому будет вызвано исключение AttributeError. Но, в самом начале функции мы создавали словарь с базовыми параметрами изображения. Вот их и выведем в случае, когда сработает исключение и метаданных в изображении найдено не будет. Поэтому, оборачиваем код в try — except и когда сработает исключение пробегаемся в цикле по созданному ранее словарику из которого извлекаем значения и выводим на печать.
Извлекаем метаданные из видео и аудио
Для извлечения метаданных из аудио и видео воспользуемся библиотекой для работы с медиафайлами ffmpeg. Конечно же, функционал данной библиотеки гораздо больше, чем просто извлечение метаданных. Но, нам требуется далеко не все, а потому, если вы желаете чуть более подробно познакомиться с данной библиотекой, можете начать вот с этой статьи.
Двигаемся дальше. Для того, чтобы работать с данной библиотекой в скрипте, нужно ее для начала установить. Если вы используете Linux, просто наберите команду:
Если же вам нужно установить данную библиотеку на Windows, перейдите на эту
После того, как данная библиотека будет установлена в вашу операционную систему, нужно установить модуль обертку, с помощью которого мы и будем работать с ffmpeg. На самом деле, модулей для работы с ffmpeg очень много. Но мы воспользуемся ffmpeg-python. Если вы читали статью с самого начала, то он у вас уже будет установлен. Если же нет, то наберите в терминале:
Теперь создадим функцию для работы с файлами. Я назвал ее vid_aud_matadata(patn_f). На вход она принимает путь к файлу. После пытается считать метаданные. И если это удается, с помощью pprint мы выводим данные на печать в необработанном виде. А именно, в формате json. При желании вы можете написать функцию, которая будет сохранять данные значения в файл json.
Обернем данный код в try — except, чтобы обработать исключение, если на входе функции будет файл, метаданные которого не получиться прочитать с помощью данной библиотеке. В исключение мы просто добавим сообщение, что данный формат файлов не поддерживается.
Как видите, извлечение метаданных из изображений, аудио или видео, не такое уж сложное занятие. С помощью данного скрипта можно извлечь метаданные из изображения, если они в нем содержаться, а также метаданные из видео и аудио файлов.
Функция обработки пользовательского ввода
Ну и теперь, когда функции для извлечения метаданных у нас уже созданы, напишем функцию для обработки пользовательского ввода. Для начала будем запрашивать путь к медиафайлу. Проверяем, существует ли данный файл. Если файл не существует, сообщаем об этом пользователю. Если же он существует, проверяем его расширение. И если расширение равно «.jpg» или «.jpeg» вызываем функцию извлечения метаданных из изображения, в которую передаем путь к файлу. Если же расширение не является изображением нужного нам формата, вызываем функцию обработки аудио и видео файлов, куда также передаем путь к файлу.
Как вы помните, ffmpeg может извлечь метаданные из файлов множества медиаформатов. И если к нему попадет картинка в формате «png», то метаданные из нее будут извлечены и выведены на экран. Тут смысл в том, что в основном, метаданные, такие как координаты, сведения о камере и прочее содержаться в основном в формате «jpg». Хотя, исключать их наличие в других форматах не совсем правильно.
Вот, для примера, метаданные, которые получены из фото, которое я сделал на телефон, предварительно включив перед этим геоданные.
А это небольшая часть метаданных из видео, которое скачано из YouTube.
Спасибо за внимание. Надеюсь, что данная информация будет вам полезна
Что понадобиться?
Для работы с изображениями установим библиотеку Pillow. Именно с ее помощью мы будем получать метаданные, если они, конечно же есть. А также установим библиотеку ffmpeg, которая работает с очень большим количеством форматов как аудио, так и видео. Причем, извлекает метаданные из фото (правда не все). Пишем в терминале команду:
pip install Pillow ffmpeg-python
После того, как все библиотеки будут установлены, импортируем нужные модули в скрипт.
Python:
import os.path
from pprint import pprint
import ffmpeg
from PIL import Image, ExifTags
Давайте приступим к созданию скрипта.
Извлекаем метаданные из файлов JPG
Создадим функцию для извлечения метаданных из изображения. Я назвал ее image_metadata(path_f). На входе она принимает только один параметр, а именно путь к файлу изображения. Затем с помощью модуля Image библиотеки Pillow откроем файл. Создадим небольшой словарь, в который добавим базовые данные о фото, такие как имя, разрешение, ширина, высота и прочие. Эти данные будут выводиться пользователю в том случае, если метеданных в фото не оказалось или они не были прочитаны.
Python:
img = Image.open(path_f)
info_dict = {
"Имя файла": os.path.split(path_f)[1],
"Разрешение изображения": img.size,
"Высота изображения": img.height,
"Ширина изображения": img.width,
"Формат изображения": img.format,
"Режим изображения": img.mode,
"Анимированное изображение": getattr(img, "is_animated", False),
"Кадров в изображении": getattr(img, "n_frames", 1)
}
Теперь, если данные exif были прочитаны и не было вызвано исключение, формируем словарь из полученных значений, к которому добавим в качестве ключа название тега. Для этого будем использовать параметр ExifTags.TAGS. Если вы распечатаете данный параметр, на выходе получите словарь с тегами, которые могут содержаться в изображении.
После того, как словарь будет сформирован, нужно вывести полученные значения пользователю на экран. Пробегаемся в цикле по словарю exif. Здесь, если мы получаем значение тега «GPSInfo», печатаем данные немного по другому, так как за данным тегом есть еще словарь со значениями широты, долготы, направления и прочие параметры. Для наших целей достаточно будет получить значение широты и долготы. Поэтому указываем значения json, где они содержаться, для вывода на экран.
Также, некоторые значения в json представлены в байтах, а потому из надо декодировать. Но, если мы будем декодировать все значения, то на экран ничего не выведется. Поэтому делаем проверку, является ли данный параметр байтами. Если да, декодируем и выводим уже декодированное значение.
Python:
exif = {ExifTags.TAGS[k]: v for k, v in img._getexif().items() if k in ExifTags.TAGS}
print(f'\n[+] Метаданные фото: {os.path.split(path_f)[1]:27}\n')
for info in exif:
if info == 'GPSInfo':
print(f'{info:27}: lat {exif[info][2]} {exif[info][1]} - long {exif[info][4]} {exif[info][3]}')
else:
if isinstance(exif[info], bytes):
info_d = exif[info].decode()
print(f'{info:25}: {info_d}')
else:
print(f'{info:25}: {exif[info]}')
Как вы помните, в изображении тегов может и не содержаться. Поэтому будет вызвано исключение AttributeError. Но, в самом начале функции мы создавали словарь с базовыми параметрами изображения. Вот их и выведем в случае, когда сработает исключение и метаданных в изображении найдено не будет. Поэтому, оборачиваем код в try — except и когда сработает исключение пробегаемся в цикле по созданному ранее словарику из которого извлекаем значения и выводим на печать.
Python:
print(f'\n[+] Информация о фото: {os.path.split(path_f)[1]:27}\n')
for k, v in info_dict.items():
print(f"{k:27}: {v}")
exit(0)
Python:
def image_metadata(path_f):
img = Image.open(path_f)
info_dict = {
"Имя файла": os.path.split(path_f)[1],
"Разрешение изображения": img.size,
"Высота изображения": img.height,
"Ширина изображения": img.width,
"Формат изображения": img.format,
"Режим изображения": img.mode,
"Анимированное изображение": getattr(img, "is_animated", False),
"Кадров в изображении": getattr(img, "n_frames", 1)
}
try:
exif = {ExifTags.TAGS[k]: v for k, v in img._getexif().items() if k in ExifTags.TAGS}
print(f'\n[+] Метаданные фото: {os.path.split(path_f)[1]:27}\n')
for info in exif:
if info == 'GPSInfo':
print(f'{info:27}: lat {exif[info][2]} {exif[info][1]} - long {exif[info][4]} {exif[info][3]}')
else:
if isinstance(exif[info], bytes):
info_d = exif[info].decode()
print(f'{info:25}: {info_d}')
else:
print(f'{info:25}: {exif[info]}')
except AttributeError:
print(f'\n[+] Информация о фото: {os.path.split(path_f)[1]:27}\n')
for k, v in info_dict.items():
print(f"{k:27}: {v}")
exit(0)
Извлекаем метаданные из видео и аудио
Для извлечения метаданных из аудио и видео воспользуемся библиотекой для работы с медиафайлами ffmpeg. Конечно же, функционал данной библиотеки гораздо больше, чем просто извлечение метаданных. Но, нам требуется далеко не все, а потому, если вы желаете чуть более подробно познакомиться с данной библиотекой, можете начать вот с этой статьи.
Двигаемся дальше. Для того, чтобы работать с данной библиотекой в скрипте, нужно ее для начала установить. Если вы используете Linux, просто наберите команду:
sudo apt-get install ffmpeg
Если же вам нужно установить данную библиотеку на Windows, перейдите на эту
Ссылка скрыта от гостей
, скачайте и установите файл.После того, как данная библиотека будет установлена в вашу операционную систему, нужно установить модуль обертку, с помощью которого мы и будем работать с ffmpeg. На самом деле, модулей для работы с ffmpeg очень много. Но мы воспользуемся ffmpeg-python. Если вы читали статью с самого начала, то он у вас уже будет установлен. Если же нет, то наберите в терминале:
pip install ffmpeg-python
Теперь создадим функцию для работы с файлами. Я назвал ее vid_aud_matadata(patn_f). На вход она принимает путь к файлу. После пытается считать метаданные. И если это удается, с помощью pprint мы выводим данные на печать в необработанном виде. А именно, в формате json. При желании вы можете написать функцию, которая будет сохранять данные значения в файл json.
Python:
print(f'\n[+] Метаданные файла: {os.path.split(patn_f)[-1]}\n')
pprint(ffmpeg.probe(patn_f)["streams"])
Обернем данный код в try — except, чтобы обработать исключение, если на входе функции будет файл, метаданные которого не получиться прочитать с помощью данной библиотеке. В исключение мы просто добавим сообщение, что данный формат файлов не поддерживается.
Python:
def vid_aud_matadata(patn_f):
try:
print(f'\n[+] Метаданные файла: {os.path.split(patn_f)[-1]}\n')
pprint(ffmpeg.probe(patn_f)["streams"])
except ffmpeg._run.Error:
print('[-] Неподдерживаемый формат')
Как видите, извлечение метаданных из изображений, аудио или видео, не такое уж сложное занятие. С помощью данного скрипта можно извлечь метаданные из изображения, если они в нем содержаться, а также метаданные из видео и аудио файлов.
Функция обработки пользовательского ввода
Ну и теперь, когда функции для извлечения метаданных у нас уже созданы, напишем функцию для обработки пользовательского ввода. Для начала будем запрашивать путь к медиафайлу. Проверяем, существует ли данный файл. Если файл не существует, сообщаем об этом пользователю. Если же он существует, проверяем его расширение. И если расширение равно «.jpg» или «.jpeg» вызываем функцию извлечения метаданных из изображения, в которую передаем путь к файлу. Если же расширение не является изображением нужного нам формата, вызываем функцию обработки аудио и видео файлов, куда также передаем путь к файлу.
Python:
if __name__ == "__main__":
path_file = input('[~] Введите путь к файлу: ')
if not os.path.exists(path_file):
print('[-] Файла не существует')
else:
if path_file.endswith(".jpg"):
image_metadata(path_file)
elif path_file.endswith(".jpeg"):
image_metadata(path_file)
else:
vid_aud_matadata(path_file)
Как вы помните, ffmpeg может извлечь метаданные из файлов множества медиаформатов. И если к нему попадет картинка в формате «png», то метаданные из нее будут извлечены и выведены на экран. Тут смысл в том, что в основном, метаданные, такие как координаты, сведения о камере и прочее содержаться в основном в формате «jpg». Хотя, исключать их наличие в других форматах не совсем правильно.
Вот, для примера, метаданные, которые получены из фото, которое я сделал на телефон, предварительно включив перед этим геоданные.
А это небольшая часть метаданных из видео, которое скачано из YouTube.
Python:
# pip install Pillow ffmpeg-python
import os.path
from pprint import pprint
import ffmpeg
from PIL import Image, ExifTags
def image_metadata(path_f):
img = Image.open(path_f)
info_dict = {
"Имя файла": os.path.split(path_f)[1],
"Разрешение изображения": img.size,
"Высота изображения": img.height,
"Ширина изображения": img.width,
"Формат изображения": img.format,
"Режим изображения": img.mode,
"Анимированное изображение": getattr(img, "is_animated", False),
"Кадров в изображении": getattr(img, "n_frames", 1)
}
try:
exif = {ExifTags.TAGS[k]: v for k, v in img._getexif().items() if k in ExifTags.TAGS}
print(f'\n[+] Метаданные фото: {os.path.split(path_f)[1]:27}\n')
for info in exif:
if info == 'GPSInfo':
print(f'{info:27}: lat {exif[info][2]} {exif[info][1]} - long {exif[info][4]} {exif[info][3]}')
else:
if isinstance(exif[info], bytes):
info_d = exif[info].decode()
print(f'{info:25}: {info_d}')
else:
print(f'{info:25}: {exif[info]}')
except AttributeError:
print(f'\n[+] Информация о фото: {os.path.split(path_f)[1]:27}\n')
for k, v in info_dict.items():
print(f"{k:27}: {v}")
exit(0)
def vid_aud_matadata(patn_f):
try:
print(f'\n[+] Метаданные файла: {os.path.split(patn_f)[-1]}\n')
pprint(ffmpeg.probe(patn_f)["streams"])
except ffmpeg._run.Error:
print('[-] Неподдерживаемый формат')
if __name__ == "__main__":
path_file = input('[~] Введите путь к файлу: ')
if not os.path.exists(path_file):
print('[-] Файла не существует')
else:
if path_file.endswith(".jpg"):
image_metadata(path_file)
elif path_file.endswith(".jpeg"):
image_metadata(path_file)
else:
vid_aud_matadata(path_file)
Спасибо за внимание. Надеюсь, что данная информация будет вам полезна
Последнее редактирование: