mirror of
https://github.com/iluvcapra/wavinfo.git
synced 2026-10-02 01:37:22 +00:00
Ruff
This commit is contained in:
+6
-1
@@ -45,7 +45,7 @@ dependencies = [
|
|||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
dev = [
|
dev = [
|
||||||
"pytest>=8.3.5",
|
"pytest>=8.3.5",
|
||||||
"ruff>=0.14.0",
|
"ruff>=0.16.8",
|
||||||
]
|
]
|
||||||
doc = [
|
doc = [
|
||||||
"sphinx>=7.1.2",
|
"sphinx>=7.1.2",
|
||||||
@@ -64,6 +64,11 @@ indent-width = 4
|
|||||||
|
|
||||||
[tool.ruff.lint]
|
[tool.ruff.lint]
|
||||||
fixable = ['ALL']
|
fixable = ['ALL']
|
||||||
|
ignore = [
|
||||||
|
'UP022', # Prefer `capture_output` over sending `stdout` and `stderr` to `PIPE`
|
||||||
|
'SIM115', # Use a context manager for opening files
|
||||||
|
'UP031', #Use format specifiers instead of percent format
|
||||||
|
]
|
||||||
|
|
||||||
# [tool.pylint]
|
# [tool.pylint]
|
||||||
# max-line-length = 88
|
# max-line-length = 88
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import io
|
import io
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
|
|
||||||
# from collections import namedtuple
|
# from collections import namedtuple
|
||||||
from typing import NamedTuple, Optional
|
from typing import NamedTuple
|
||||||
|
|
||||||
from lxml import etree as ET
|
from lxml import etree as ET
|
||||||
|
|
||||||
@@ -76,7 +78,7 @@ class SteinbergMetadata:
|
|||||||
self.parsed = xml.find(self.Steinberg_xpath)
|
self.parsed = xml.find(self.Steinberg_xpath)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def audio_speaker_arrangement(self) -> Optional[AudioSpeakerArrangement]:
|
def audio_speaker_arrangement(self) -> AudioSpeakerArrangement | None:
|
||||||
"""
|
"""
|
||||||
`AudioSpeakerArrangement` property
|
`AudioSpeakerArrangement` property
|
||||||
"""
|
"""
|
||||||
@@ -87,7 +89,7 @@ class SteinbergMetadata:
|
|||||||
return type(self).AudioSpeakerArrangement(int(val.text))
|
return type(self).AudioSpeakerArrangement(int(val.text))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sample_format_size(self) -> Optional[int]:
|
def sample_format_size(self) -> int | None:
|
||||||
"""
|
"""
|
||||||
AudioSampleFormatSize
|
AudioSampleFormatSize
|
||||||
"""
|
"""
|
||||||
@@ -96,7 +98,7 @@ class SteinbergMetadata:
|
|||||||
return int(val.text)
|
return int(val.text)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def media_company(self) -> Optional[str]:
|
def media_company(self) -> str | None:
|
||||||
"""
|
"""
|
||||||
MediaCompany
|
MediaCompany
|
||||||
"""
|
"""
|
||||||
@@ -105,7 +107,7 @@ class SteinbergMetadata:
|
|||||||
return val.text
|
return val.text
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def media_drop_frames(self) -> Optional[bool]:
|
def media_drop_frames(self) -> bool | None:
|
||||||
"""
|
"""
|
||||||
MediaDropFrames
|
MediaDropFrames
|
||||||
"""
|
"""
|
||||||
@@ -114,7 +116,7 @@ class SteinbergMetadata:
|
|||||||
return val.text == "1"
|
return val.text == "1"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def media_duration(self) -> Optional[float]:
|
def media_duration(self) -> float | None:
|
||||||
"""
|
"""
|
||||||
MediaDuration
|
MediaDuration
|
||||||
"""
|
"""
|
||||||
@@ -122,33 +124,29 @@ class SteinbergMetadata:
|
|||||||
if val is not None:
|
if val is not None:
|
||||||
return float(val.text)
|
return float(val.text)
|
||||||
|
|
||||||
@property
|
# @property
|
||||||
def media_start_time(self) -> Optional[float]:
|
# def media_start_time(self) -> float | None:
|
||||||
"""
|
# """
|
||||||
MediaStartTime
|
# MediaStartTime
|
||||||
"""
|
# """
|
||||||
pass
|
|
||||||
|
|
||||||
@property
|
# @property
|
||||||
def media_track_title(self) -> Optional[str]:
|
# def media_track_title(self) -> str | None:
|
||||||
"""
|
# """
|
||||||
MediaTrackTitle
|
# MediaTrackTitle
|
||||||
"""
|
# """
|
||||||
pass
|
|
||||||
|
|
||||||
@property
|
# @property
|
||||||
def program_name(self) -> Optional[str]:
|
# def program_name(self) -> str | None:
|
||||||
"""
|
# """
|
||||||
ProgramName
|
# ProgramName
|
||||||
"""
|
# """
|
||||||
pass
|
|
||||||
|
|
||||||
@property
|
# @property
|
||||||
def program_version(self) -> Optional[str]:
|
# def program_version(self) -> str | None:
|
||||||
"""
|
# """
|
||||||
ProgramVersion
|
# ProgramVersion
|
||||||
"""
|
# """
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class WavIXMLFormat:
|
class WavIXMLFormat:
|
||||||
@@ -166,7 +164,7 @@ class WavIXMLFormat:
|
|||||||
parser = ET.XMLParser(recover=True)
|
parser = ET.XMLParser(recover=True)
|
||||||
self.parsed: ET.ElementTree = ET.parse(xml_bytes, parser=parser)
|
self.parsed: ET.ElementTree = ET.parse(xml_bytes, parser=parser)
|
||||||
|
|
||||||
def _get_text_value(self, xpath) -> Optional[str]:
|
def _get_text_value(self, xpath) -> str | None:
|
||||||
e = self.parsed.find("./" + xpath)
|
e = self.parsed.find("./" + xpath)
|
||||||
if e is not None:
|
if e is not None:
|
||||||
return e.text
|
return e.text
|
||||||
@@ -200,35 +198,35 @@ class WavIXMLFormat:
|
|||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def project(self) -> Optional[str]:
|
def project(self) -> str | None:
|
||||||
"""
|
"""
|
||||||
The project/film name entered for the recording.
|
The project/film name entered for the recording.
|
||||||
"""
|
"""
|
||||||
return self._get_text_value("PROJECT")
|
return self._get_text_value("PROJECT")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def scene(self) -> Optional[str]:
|
def scene(self) -> str | None:
|
||||||
"""
|
"""
|
||||||
Scene/slate.
|
Scene/slate.
|
||||||
"""
|
"""
|
||||||
return self._get_text_value("SCENE")
|
return self._get_text_value("SCENE")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def take(self) -> Optional[str]:
|
def take(self) -> str | None:
|
||||||
"""
|
"""
|
||||||
Take number.
|
Take number.
|
||||||
"""
|
"""
|
||||||
return self._get_text_value("TAKE")
|
return self._get_text_value("TAKE")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tape(self) -> Optional[str]:
|
def tape(self) -> str | None:
|
||||||
"""
|
"""
|
||||||
Tape name.
|
Tape name.
|
||||||
"""
|
"""
|
||||||
return self._get_text_value("TAPE")
|
return self._get_text_value("TAPE")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def family_uid(self) -> Optional[str]:
|
def family_uid(self) -> str | None:
|
||||||
"""
|
"""
|
||||||
The globally-unique ID for this file family. This may be in the format
|
The globally-unique ID for this file family. This may be in the format
|
||||||
of a GUID, or an EBU Rec 9 source identifier, or some other dumb
|
of a GUID, or an EBU Rec 9 source identifier, or some other dumb
|
||||||
@@ -237,14 +235,14 @@ class WavIXMLFormat:
|
|||||||
return self._get_text_value("FILE_SET/FAMILY_UID")
|
return self._get_text_value("FILE_SET/FAMILY_UID")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def family_name(self) -> Optional[str]:
|
def family_name(self) -> str | None:
|
||||||
"""
|
"""
|
||||||
The name of this file's file family.
|
The name of this file's file family.
|
||||||
"""
|
"""
|
||||||
return self._get_text_value("FILE_SET/FAMILY_NAME")
|
return self._get_text_value("FILE_SET/FAMILY_NAME")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def steinberg(self) -> Optional[SteinbergMetadata]:
|
def steinberg(self) -> SteinbergMetadata | None:
|
||||||
"""
|
"""
|
||||||
Steinberg vendor iXML metadata if present.
|
Steinberg vendor iXML metadata if present.
|
||||||
"""
|
"""
|
||||||
@@ -254,12 +252,12 @@ class WavIXMLFormat:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
return dict(
|
return {
|
||||||
track_list=list(map(lambda x: x._asdict(), self.track_list)),
|
"track_list": [x._asdict() for x in self.track_list],
|
||||||
project=self.project,
|
"project": self.project,
|
||||||
scene=self.scene,
|
"scene": self.scene,
|
||||||
take=self.take,
|
"take": self.take,
|
||||||
tape=self.tape,
|
"tape": self.tape,
|
||||||
family_uid=self.family_uid,
|
"family_uid": self.family_uid,
|
||||||
family_name=self.family_name,
|
"family_name": self.family_name,
|
||||||
)
|
}
|
||||||
|
|||||||
+18
-21
@@ -1,8 +1,9 @@
|
|||||||
# -*- coding: utf-8 -*-
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
import struct
|
import struct
|
||||||
from typing import Any, Generator, NamedTuple, Optional
|
from typing import Any, Generator, NamedTuple
|
||||||
|
|
||||||
from .riff_parser import ChunkDescriptor, ListChunkDescriptor, parse_chunk
|
from .riff_parser import ChunkDescriptor, ListChunkDescriptor, parse_chunk
|
||||||
from .wave_adm_reader import WavADMReader
|
from .wave_adm_reader import WavADMReader
|
||||||
@@ -58,31 +59,31 @@ class WavInfoReader:
|
|||||||
self.bext_encoding = bext_encoding
|
self.bext_encoding = bext_encoding
|
||||||
|
|
||||||
#: Wave audio data format.
|
#: Wave audio data format.
|
||||||
self.fmt: Optional[WavAudioFormat] = None
|
self.fmt: WavAudioFormat | None = None
|
||||||
|
|
||||||
#: Statistics of the `data` section.
|
#: Statistics of the `data` section.
|
||||||
self.data: Optional[WavDataDescriptor] = None
|
self.data: WavDataDescriptor | None = None
|
||||||
|
|
||||||
#: Broadcast-Wave metadata.
|
#: Broadcast-Wave metadata.
|
||||||
self.bext: Optional[WavBextReader] = None
|
self.bext: WavBextReader | None = None
|
||||||
|
|
||||||
#: iXML metadata.
|
#: iXML metadata.
|
||||||
self.ixml: Optional[WavIXMLFormat] = None
|
self.ixml: WavIXMLFormat | None = None
|
||||||
|
|
||||||
#: ADM Audio Definiton Model metadata.
|
#: ADM Audio Definiton Model metadata.
|
||||||
self.adm: Optional[WavADMReader] = None
|
self.adm: WavADMReader | None = None
|
||||||
|
|
||||||
#: Dolby bitstream metadata.
|
#: Dolby bitstream metadata.
|
||||||
self.dolby: Optional[WavDolbyMetadataReader] = None
|
self.dolby: WavDolbyMetadataReader | None = None
|
||||||
|
|
||||||
#: RIFF INFO metadata.
|
#: RIFF INFO metadata.
|
||||||
self.info: Optional[WavInfoChunkReader] = None
|
self.info: WavInfoChunkReader | None = None
|
||||||
|
|
||||||
#: RIFF cues markers, labels, and notes.
|
#: RIFF cues markers, labels, and notes.
|
||||||
self.cues: Optional[WavCuesReader] = None
|
self.cues: WavCuesReader | None = None
|
||||||
|
|
||||||
#: Sampler `smpl` metadata
|
#: Sampler `smpl` metadata
|
||||||
self.smpl: Optional[WavSmplReader] = None
|
self.smpl: WavSmplReader | None = None
|
||||||
|
|
||||||
if hasattr(path, "read"):
|
if hasattr(path, "read"):
|
||||||
self.get_wav_info(path)
|
self.get_wav_info(path)
|
||||||
@@ -97,8 +98,8 @@ class WavInfoReader:
|
|||||||
|
|
||||||
self.path = absolute_path
|
self.path = absolute_path
|
||||||
|
|
||||||
with open(path, "rb") as path:
|
with open(path, "rb") as file:
|
||||||
self.get_wav_info(path)
|
self.get_wav_info(file)
|
||||||
|
|
||||||
def get_wav_info(self, wavfile):
|
def get_wav_info(self, wavfile):
|
||||||
chunks = parse_chunk(wavfile)
|
chunks = parse_chunk(wavfile)
|
||||||
@@ -117,9 +118,7 @@ class WavInfoReader:
|
|||||||
self.smpl = self._get_sampler_loops(wavfile)
|
self.smpl = self._get_sampler_loops(wavfile)
|
||||||
self.data = self._describe_data()
|
self.data = self._describe_data()
|
||||||
|
|
||||||
def _find_chunk_data(
|
def _find_chunk_data(self, ident, from_stream, default_none=False) -> bytes | None:
|
||||||
self, ident, from_stream, default_none=False
|
|
||||||
) -> Optional[bytes]:
|
|
||||||
top_chunks = (
|
top_chunks = (
|
||||||
chunk
|
chunk
|
||||||
for chunk in self.main_list
|
for chunk in self.main_list
|
||||||
@@ -130,7 +129,7 @@ class WavInfoReader:
|
|||||||
|
|
||||||
return chunk_descriptor.read_data(from_stream) if chunk_descriptor else None
|
return chunk_descriptor.read_data(from_stream) if chunk_descriptor else None
|
||||||
|
|
||||||
def _find_list_chunk(self, signature) -> Optional[ListChunkDescriptor]:
|
def _find_list_chunk(self, signature) -> ListChunkDescriptor | None:
|
||||||
top_chunks = (
|
top_chunks = (
|
||||||
chunk
|
chunk
|
||||||
for chunk in self.main_list
|
for chunk in self.main_list
|
||||||
@@ -261,10 +260,8 @@ class WavInfoReader:
|
|||||||
if self.__getattribute__(scope)
|
if self.__getattribute__(scope)
|
||||||
else {}
|
else {}
|
||||||
)
|
)
|
||||||
for key in mdict.keys():
|
for key in mdict:
|
||||||
yield scope, key, mdict[key]
|
yield scope, key, mdict[key]
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "WavInfoReader({}, {}, {})".format(
|
return f"WavInfoReader({self.path}, {self.info_encoding}, {self.bext_encoding})"
|
||||||
self.path, self.info_encoding, self.bext_encoding
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import struct
|
import struct
|
||||||
from typing import List, NamedTuple, Tuple
|
from typing import NamedTuple
|
||||||
|
|
||||||
|
|
||||||
class WaveSmplLoop(NamedTuple):
|
class WaveSmplLoop(NamedTuple):
|
||||||
@@ -69,13 +71,13 @@ class WavSmplReader:
|
|||||||
|
|
||||||
#: The SMPTE offset to apply, as a tuple of four ints representing
|
#: The SMPTE offset to apply, as a tuple of four ints representing
|
||||||
#: hh, mm, ss, ff
|
#: hh, mm, ss, ff
|
||||||
self.smpte_offset: Tuple[int, int, int, int] = unpacked_data[6:10]
|
self.smpte_offset: tuple[int, int, int, int] = unpacked_data[6:10]
|
||||||
|
|
||||||
loop_count = unpacked_data[10]
|
loop_count = unpacked_data[10]
|
||||||
sampler_udata_length = unpacked_data[11]
|
sampler_udata_length = unpacked_data[11]
|
||||||
|
|
||||||
#: List of loops in the file.
|
#: List of loops in the file.
|
||||||
self.sample_loops: List[WaveSmplLoop] = []
|
self.sample_loops: list[WaveSmplLoop] = []
|
||||||
|
|
||||||
loop_buffer = smpl_data[header_size : header_size + loop_size * loop_count]
|
loop_buffer = smpl_data[header_size : header_size + loop_size * loop_count]
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
""" """
|
"""
|
||||||
|
wavfind.py
|
||||||
|
|
||||||
|
Under construction! Do Not Use!
|
||||||
|
"""
|
||||||
import sys
|
import sys
|
||||||
from optparse import OptionGroup, OptionParser
|
from optparse import OptionGroup, OptionParser
|
||||||
|
|
||||||
@@ -21,7 +24,7 @@ def main():
|
|||||||
|
|
||||||
primaries.add_option("--desc", help="Search descriptions", metavar="DESC")
|
primaries.add_option("--desc", help="Search descriptions", metavar="DESC")
|
||||||
|
|
||||||
(options, args) = parser.parse_args(sys.argv)
|
(_options, _args) = parser.parse_args(sys.argv)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
+5
-3
@@ -42,12 +42,14 @@ class TestADMWave(TestCase):
|
|||||||
adm = info.adm
|
adm = info.adm
|
||||||
assert adm is not None
|
assert adm is not None
|
||||||
t1 = adm.track_info(0)
|
t1 = adm.track_info(0)
|
||||||
self.assertTrue("channel_format_name" in t1.keys())
|
assert t1 is not None
|
||||||
|
self.assertTrue("channel_format_name" in t1)
|
||||||
self.assertEqual("RoomCentricLeft", t1["channel_format_name"])
|
self.assertEqual("RoomCentricLeft", t1["channel_format_name"])
|
||||||
|
|
||||||
self.assertTrue("pack_format_name" in t1.keys())
|
self.assertTrue("pack_format_name" in t1)
|
||||||
self.assertEqual("AtmosCustomPackFormat1", t1["pack_format_name"])
|
self.assertEqual("AtmosCustomPackFormat1", t1["pack_format_name"])
|
||||||
|
|
||||||
t10 = adm.track_info(10)
|
t10 = adm.track_info(10)
|
||||||
self.assertTrue("content_name" in t10.keys())
|
assert t10 is not None
|
||||||
|
self.assertTrue("content_name" in t10)
|
||||||
self.assertEqual("Dialog", t10["content_name"])
|
self.assertEqual("Dialog", t10["content_name"])
|
||||||
|
|||||||
+3
-12
@@ -9,24 +9,15 @@ from wavinfo.__main__ import main
|
|||||||
class MainTest(unittest.TestCase):
|
class MainTest(unittest.TestCase):
|
||||||
def test_empty_argv(self):
|
def test_empty_argv(self):
|
||||||
with patch.object(sys, "argv", []):
|
with patch.object(sys, "argv", []):
|
||||||
try:
|
main()
|
||||||
main()
|
|
||||||
except Exception as e:
|
|
||||||
self.fail(f"main() throwing an exception: {e}")
|
|
||||||
|
|
||||||
def test_a_file(self):
|
def test_a_file(self):
|
||||||
for path in glob.glob("tests/test_files/**/*.wav"):
|
for path in glob.glob("tests/test_files/**/*.wav"):
|
||||||
with patch.object(sys, "argv", ["TEST", path]):
|
with patch.object(sys, "argv", ["TEST", path]):
|
||||||
try:
|
main()
|
||||||
main()
|
|
||||||
except Exception as e:
|
|
||||||
self.fail(f"main() throwing an exception: {e}")
|
|
||||||
|
|
||||||
def test_ixml(self):
|
def test_ixml(self):
|
||||||
with patch.object(
|
with patch.object(
|
||||||
sys, "argv", ["TEST", "--ixml", "tests/test_files/sounddevices/A101_1.WAV"]
|
sys, "argv", ["TEST", "--ixml", "tests/test_files/sounddevices/A101_1.WAV"]
|
||||||
):
|
):
|
||||||
try:
|
main()
|
||||||
main()
|
|
||||||
except Exception as e:
|
|
||||||
self.fail(f"main() throwing an exception: {e}")
|
|
||||||
|
|||||||
+7
-9
@@ -11,12 +11,10 @@ class TestWalk(unittest.TestCase):
|
|||||||
|
|
||||||
tested_data, tested_format = False, False
|
tested_data, tested_format = False, False
|
||||||
for scope, key, value in info.walk():
|
for scope, key, value in info.walk():
|
||||||
if scope == "fmt":
|
if scope == "fmt" and key == "channel_count":
|
||||||
if key == "channel_count":
|
|
||||||
tested_format = True
|
tested_format = True
|
||||||
self.assertEqual(value, 2)
|
self.assertEqual(value, 2)
|
||||||
if scope == "data":
|
if scope == "data" and key == "frame_count":
|
||||||
if key == "frame_count":
|
|
||||||
tested_data = True
|
tested_data = True
|
||||||
self.assertEqual(value, 144140)
|
self.assertEqual(value, 144140)
|
||||||
|
|
||||||
@@ -26,11 +24,11 @@ class TestWalk(unittest.TestCase):
|
|||||||
for file in glob.glob("tests/test_files/**/*.wav"):
|
for file in glob.glob("tests/test_files/**/*.wav"):
|
||||||
info = wavinfo.WavInfoReader(file)
|
info = wavinfo.WavInfoReader(file)
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
for _, _, _ in info.walk():
|
for _, _, _ in info.walk():
|
||||||
pass
|
pass
|
||||||
except Exception as e:
|
# except Exception as e:
|
||||||
self.fail(f"Failed to walk metadata in file {file}: {e}")
|
# self.fail(f"Failed to walk metadata in file {file}: {e}")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class TestWaveInfo(TestCase):
|
|||||||
info = wavinfo.WavInfoReader(wav_file)
|
info = wavinfo.WavInfoReader(wav_file)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
info.__repr__(),
|
info.__repr__(),
|
||||||
"WavInfoReader({}, latin_1, ascii)".format(os.path.abspath(wav_file)),
|
f"WavInfoReader({os.path.abspath(wav_file)}, latin_1, ascii)",
|
||||||
)
|
)
|
||||||
self.assertIsNotNone(info)
|
self.assertIsNotNone(info)
|
||||||
|
|
||||||
|
|||||||
+5
-17
@@ -1,7 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
import os.path
|
import os.path
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
|
||||||
from subprocess import PIPE
|
from subprocess import PIPE
|
||||||
|
|
||||||
FFPROBE = "ffprobe"
|
FFPROBE = "ffprobe"
|
||||||
@@ -9,23 +8,12 @@ FFPROBE = "ffprobe"
|
|||||||
|
|
||||||
def ffprobe(path):
|
def ffprobe(path):
|
||||||
arguments = [FFPROBE, "-of", "json", "-show_format", "-show_streams", path]
|
arguments = [FFPROBE, "-of", "json", "-show_format", "-show_streams", path]
|
||||||
if int(sys.version[0]) < 3:
|
process = subprocess.run(arguments, stdin=None, stdout=PIPE, stderr=PIPE, check=True)
|
||||||
process = subprocess.Popen(arguments, stdout=PIPE)
|
if process.returncode == 0:
|
||||||
process.wait()
|
output_str = process.stdout.decode("utf-8")
|
||||||
if process.returncode == 0:
|
return json.loads(output_str)
|
||||||
output = process.communicate()[0]
|
|
||||||
if output:
|
|
||||||
output_str = output.decode("utf-8")
|
|
||||||
return json.loads(output_str)
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
else:
|
else:
|
||||||
process = subprocess.run(arguments, stdin=None, stdout=PIPE, stderr=PIPE)
|
return None
|
||||||
if process.returncode == 0:
|
|
||||||
output_str = process.stdout.decode("utf-8")
|
|
||||||
return json.loads(output_str)
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def all_files():
|
def all_files():
|
||||||
|
|||||||
Reference in New Issue
Block a user