forked from pool/python-pydub
Accepting request 878359 from devel:languages:python
OBS-URL: https://build.opensuse.org/request/show/878359 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-pydub?expand=0&rev=7
This commit is contained in:
@@ -1,195 +0,0 @@
|
||||
From 01383a88fe6bd574e3e47547ee6b7828af52a344 Mon Sep 17 00:00:00 2001
|
||||
From: Antonio Larrosa <antonio.larrosa@gmail.com>
|
||||
Date: Tue, 19 Feb 2019 20:01:39 +0100
|
||||
Subject: [PATCH] Skip tests that use unavailable codecs
|
||||
|
||||
In openSUSE, ffmpeg doesn't support aac audio and some other codecs due
|
||||
to legal reasons. When building the pydub packages and running tests,
|
||||
some of these fail because the files format_test.m4a, creative_common.mp4
|
||||
wrong_extension.aac can't be read since they use aac audio.
|
||||
|
||||
This commit adds two functions get_supported_decoders and
|
||||
get_supported_encoders that return a set with the decoders/encoders that
|
||||
are supported. Then it also adds some decorators to the tests to skip
|
||||
the tests that use unsupported codecs.
|
||||
|
||||
Note that functools.lru_cache was added in python 3.3, so it can't be
|
||||
used and that's the reason I added a small implementation of a cache
|
||||
decorator so we don't have to execute ffmpeg for every call to get
|
||||
the supported codecs.
|
||||
|
||||
https://github.com/jiaaro/pydub/pull/362
|
||||
---
|
||||
pydub/utils.py | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
test/test.py | 22 ++++++++++++++++++++
|
||||
2 files changed, 76 insertions(+)
|
||||
|
||||
diff --git a/pydub/utils.py b/pydub/utils.py
|
||||
index def1a72..8cf0262 100644
|
||||
--- a/pydub/utils.py
|
||||
+++ b/pydub/utils.py
|
||||
@@ -8,6 +8,7 @@ from subprocess import Popen, PIPE
|
||||
from math import log, ceil
|
||||
from tempfile import TemporaryFile
|
||||
from warnings import warn
|
||||
+from functools import wraps
|
||||
|
||||
try:
|
||||
import audioop
|
||||
@@ -351,3 +352,56 @@ def mediainfo(filepath):
|
||||
info[key] = value
|
||||
|
||||
return info
|
||||
+
|
||||
+
|
||||
+def cache_codecs(function):
|
||||
+ cache = {}
|
||||
+
|
||||
+ @wraps(function)
|
||||
+ def wrapper():
|
||||
+ try:
|
||||
+ return cache[0]
|
||||
+ except:
|
||||
+ cache[0] = function()
|
||||
+ return cache[0]
|
||||
+
|
||||
+ return wrapper
|
||||
+
|
||||
+
|
||||
+@cache_codecs
|
||||
+def get_supported_codecs():
|
||||
+ encoder = get_encoder_name()
|
||||
+ command = [encoder, "-codecs"]
|
||||
+ res = Popen(command, stdout=PIPE, stderr=PIPE)
|
||||
+ output = res.communicate()[0].decode("utf-8")
|
||||
+ if res.returncode != 0:
|
||||
+ return []
|
||||
+
|
||||
+ if sys.platform == 'win32':
|
||||
+ output = output.replace("\r", "")
|
||||
+
|
||||
+
|
||||
+ rgx = re.compile(r"^([D.][E.][AVS.][I.][L.][S.]) (\w*) +(.*)")
|
||||
+ decoders = set()
|
||||
+ encoders = set()
|
||||
+ for line in output.split('\n'):
|
||||
+ match = rgx.match(line.strip())
|
||||
+ if not match:
|
||||
+ continue
|
||||
+ flags, codec, name = match.groups()
|
||||
+
|
||||
+ if flags[0] == 'D':
|
||||
+ decoders.add(codec)
|
||||
+
|
||||
+ if flags[1] == 'E':
|
||||
+ encoders.add(codec)
|
||||
+
|
||||
+ return (decoders, encoders)
|
||||
+
|
||||
+
|
||||
+def get_supported_decoders():
|
||||
+ return get_supported_codecs()[0]
|
||||
+
|
||||
+
|
||||
+def get_supported_encoders():
|
||||
+ return get_supported_codecs()[1]
|
||||
diff --git a/test/test.py b/test/test.py
|
||||
index 415f14c..bc5d0c7 100644
|
||||
--- a/test/test.py
|
||||
+++ b/test/test.py
|
||||
@@ -18,6 +18,8 @@ from pydub.utils import (
|
||||
make_chunks,
|
||||
mediainfo,
|
||||
get_encoder_name,
|
||||
+ get_supported_decoders,
|
||||
+ get_supported_encoders,
|
||||
)
|
||||
from pydub.exceptions import (
|
||||
InvalidTag,
|
||||
@@ -670,6 +672,8 @@ class AudioSegmentTests(unittest.TestCase):
|
||||
if sys.platform == 'win32':
|
||||
os.remove(tmp_mp3_file.name)
|
||||
|
||||
+ @unittest.skipUnless('aac' in get_supported_decoders(),
|
||||
+ "Unsupported codecs")
|
||||
def test_formats(self):
|
||||
seg_m4a = AudioSegment.from_file(
|
||||
os.path.join(data_dir, 'format_test.m4a'), "m4a")
|
||||
@@ -688,6 +692,8 @@ class AudioSegmentTests(unittest.TestCase):
|
||||
wav = AudioSegment.from_wav(wav_file)
|
||||
self.assertEqual(wav.duration_seconds, self.seg1.duration_seconds)
|
||||
|
||||
+ @unittest.skipUnless('aac' in get_supported_decoders(),
|
||||
+ "Unsupported codecs")
|
||||
def test_autodetect_format(self):
|
||||
aac_path = os.path.join(data_dir, 'wrong_extension.aac')
|
||||
fn = partial(AudioSegment.from_file, aac_path, "aac")
|
||||
@@ -720,21 +726,29 @@ class AudioSegmentTests(unittest.TestCase):
|
||||
AudioSegment.from_file(self.mp3_file_path).export(tmp_webm_file,
|
||||
format="webm")
|
||||
|
||||
+ @unittest.skipUnless('aac' in get_supported_decoders(),
|
||||
+ "Unsupported codecs")
|
||||
def test_export_mp4_as_ogg(self):
|
||||
with NamedTemporaryFile('w+b', suffix='.ogg') as tmp_ogg_file:
|
||||
AudioSegment.from_file(self.mp4_file_path).export(tmp_ogg_file,
|
||||
format="ogg")
|
||||
|
||||
+ @unittest.skipUnless('aac' in get_supported_decoders(),
|
||||
+ "Unsupported codecs")
|
||||
def test_export_mp4_as_mp3(self):
|
||||
with NamedTemporaryFile('w+b', suffix='.mp3') as tmp_mp3_file:
|
||||
AudioSegment.from_file(self.mp4_file_path).export(tmp_mp3_file,
|
||||
format="mp3")
|
||||
|
||||
+ @unittest.skipUnless('aac' in get_supported_decoders(),
|
||||
+ "Unsupported codecs")
|
||||
def test_export_mp4_as_wav(self):
|
||||
with NamedTemporaryFile('w+b', suffix='.wav') as tmp_wav_file:
|
||||
AudioSegment.from_file(self.mp4_file_path).export(tmp_wav_file,
|
||||
format="mp3")
|
||||
|
||||
+ @unittest.skipUnless('aac' in get_supported_decoders(),
|
||||
+ "Unsupported codecs")
|
||||
def test_export_mp4_as_mp3_with_tags(self):
|
||||
with NamedTemporaryFile('w+b', suffix='.mp3') as tmp_mp3_file:
|
||||
tags_dict = {
|
||||
@@ -746,6 +760,8 @@ class AudioSegmentTests(unittest.TestCase):
|
||||
format="mp3",
|
||||
tags=tags_dict)
|
||||
|
||||
+ @unittest.skipUnless('aac' in get_supported_decoders(),
|
||||
+ "Unsupported codecs")
|
||||
def test_export_mp4_as_mp3_with_tags_raises_exception_when_tags_are_not_a_dictionary(self):
|
||||
with NamedTemporaryFile('w+b', suffix='.mp3') as tmp_mp3_file:
|
||||
json = '{"title": "The Title You Want", "album": "Name of the Album", "artist": "Artist\'s name"}'
|
||||
@@ -754,6 +770,8 @@ class AudioSegmentTests(unittest.TestCase):
|
||||
format="mp3", tags=json)
|
||||
self.assertRaises(InvalidTag, func)
|
||||
|
||||
+ @unittest.skipUnless('aac' in get_supported_decoders(),
|
||||
+ "Unsupported codecs")
|
||||
def test_export_mp4_as_mp3_with_tags_raises_exception_when_id3version_is_wrong(self):
|
||||
tags = {'artist': 'Artist', 'title': 'Title'}
|
||||
with NamedTemporaryFile('w+b', suffix='.mp3') as tmp_mp3_file:
|
||||
@@ -766,6 +784,8 @@ class AudioSegmentTests(unittest.TestCase):
|
||||
)
|
||||
self.assertRaises(InvalidID3TagVersion, func)
|
||||
|
||||
+ @unittest.skipUnless('aac' in get_supported_decoders(),
|
||||
+ "Unsupported codecs")
|
||||
def test_export_mp3_with_tags(self):
|
||||
tags = {'artist': 'Mozart', 'title': 'The Magic Flute'}
|
||||
|
||||
@@ -883,6 +903,8 @@ class AudioSegmentTests(unittest.TestCase):
|
||||
# average volume should be reduced
|
||||
self.assertTrue(compressed.rms < self.seg1.rms)
|
||||
|
||||
+ @unittest.skipUnless('aac' in get_supported_decoders(),
|
||||
+ "Unsupported codecs")
|
||||
def test_exporting_to_ogg_uses_default_codec_when_codec_param_is_none(self):
|
||||
delete = sys.platform != 'win32'
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a5ee51e6bac1e3f64eefd5176aac3299a75e4deec9ad6fef87c3d936f4a034dc
|
||||
size 27180893
|
3
pydub-0.25.1.tar.gz
Normal file
3
pydub-0.25.1.tar.gz
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:94f423c9acc9f361203e82a204420bb8fb85731d0586ebd2c1509fbeadeabad6
|
||||
size 27555582
|
@@ -1,3 +1,49 @@
|
||||
-------------------------------------------------------------------
|
||||
Wed Mar 10 20:05:05 UTC 2021 - Ben Greiner <code@bnavigator.de>
|
||||
|
||||
- Update to 0.25.1
|
||||
* Fix crashing bug in new scipy-powered EQ effects
|
||||
- Release 0.25.0
|
||||
* Don't show a runtime warning about the optional ffplay
|
||||
dependency being missing until someone trys to use it
|
||||
* Documentation improvements
|
||||
* Python 3.9 support
|
||||
* Improved efficiency of loading wave files with pydub.
|
||||
AudioSegment.from_file()
|
||||
* Ensure pydub.AudioSegment().export() always retuns files with
|
||||
a seek position at the beginning of the file
|
||||
* Added more EQ effects to pydub.scipy_effects (requires scipy
|
||||
to be installed)
|
||||
* Fix a packaging bug where the LICENSE file was not included in
|
||||
the source distribution
|
||||
* Add a way to instantiate a pydub.AudioSegment() with a portion
|
||||
of an audio file via pydub.AudioSegment().from_file()
|
||||
- Release 0.24.1
|
||||
* Fix bug where ffmpeg errors in Python 3 are illegible
|
||||
* Fix bug where split_on_silence fails when there are one or
|
||||
fewer nonsilent segments
|
||||
* Fix bug in fallback audioop implementation
|
||||
- Release 0.24.0
|
||||
* Fix inconsistent handling of 8-bit audio
|
||||
* Fix bug where certain files will fail to parse
|
||||
* Fix bug where pyaudio stream is not closed on error
|
||||
* Allow codecs and parameters in wav and raw export
|
||||
* Fix bug in pydub.AudioSegment.from_file where supplied codec
|
||||
is ignored
|
||||
* Allow pydub.silence.split_on_silence to take a boolean for
|
||||
keep_silence
|
||||
* Fix bug where pydub.silence.split_on_silence sometimes adds
|
||||
non-silence from adjacent segments
|
||||
* Fix bug where pydub.AudioSegment.extract_wav_headers fails on
|
||||
empty wav files
|
||||
* Add new function pydub.silence.detect_leading_silence
|
||||
* Support conversion between an arbitrary number of channels and
|
||||
mono in pydub.AudioSegment.set_channels
|
||||
* Fix several issues related to reading from filelike objects
|
||||
- Drop 0001-Skip-tests-that-use-unavailable-codecs.patch merged
|
||||
upstream
|
||||
- Reinstate python36 build. SciPy is optional
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Sat Feb 13 10:14:16 UTC 2021 - Dirk Müller <dmueller@suse.com>
|
||||
|
||||
|
@@ -17,22 +17,19 @@
|
||||
|
||||
|
||||
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
|
||||
%global skip_python36 1
|
||||
Name: python-pydub
|
||||
Version: 0.23.1
|
||||
Version: 0.25.1
|
||||
Release: 0
|
||||
Summary: Audio manipulation with Python
|
||||
License: MIT
|
||||
Group: Development/Languages/Python
|
||||
URL: https://github.com/jiaaro/pydub
|
||||
Source: https://github.com/jiaaro/pydub/archive/v%{version}.tar.gz#/pydub-%{version}.tar.gz
|
||||
# PATCH-FIX-UPSTREAM
|
||||
Patch0: 0001-Skip-tests-that-use-unavailable-codecs.patch
|
||||
BuildRequires: %{python_module scipy}
|
||||
BuildRequires: %{python_module setuptools}
|
||||
BuildRequires: fdupes
|
||||
BuildRequires: ffmpeg
|
||||
BuildRequires: python-rpm-macros
|
||||
BuildRequires: %{python_module scipy if (%python-base without python36-base)}
|
||||
Recommends: python-scipy
|
||||
Recommends: python-simpleaudio
|
||||
Requires: ffmpeg
|
||||
@@ -45,7 +42,6 @@ A Python module to manipulate audio with a high level interface.
|
||||
|
||||
%prep
|
||||
%setup -q -n pydub-%{version}
|
||||
%patch0 -p1
|
||||
|
||||
%build
|
||||
%python_build
|
||||
@@ -55,7 +51,7 @@ A Python module to manipulate audio with a high level interface.
|
||||
%python_expand %fdupes %{buildroot}%{$python_sitelib}
|
||||
|
||||
%check
|
||||
%python_expand PYTHONPATH=%{buildroot}%{$python_sitelib} $python test/test.py
|
||||
%pyunittest -v test.test
|
||||
|
||||
%files %{python_files}
|
||||
%license LICENSE
|
||||
|
Reference in New Issue
Block a user