forked from pool/python-pydub
Accepting request 677638 from home:alarrosa:branches:devel:languages:python
- Enable tests. Changed source to the github release, which also removes the need to provide a copy of the LICENSE file. - Add 0001-Skip-tests-that-use-unavailable-codecs.patch to skip tests that use codecs not supported by the official ffmpeg package - Update to 0.23.1 * Fix bug in passing ffmpeg/avconv parameters for pydub.AudioSegment.from_mp3(), pydub.AudioSegment.from_flv(), pydub.AudioSegment.from_ogg() and pydub.AudioSegment.from_wav() * Fix logic bug in pydub.effects.strip_silence() OBS-URL: https://build.opensuse.org/request/show/677638 OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-pydub?expand=0&rev=11
This commit is contained in:
committed by
Git OBS Bridge
parent
f6b9b82748
commit
261b3349b9
195
0001-Skip-tests-that-use-unavailable-codecs.patch
Normal file
195
0001-Skip-tests-that-use-unavailable-codecs.patch
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
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
|
||||||
|
|
20
LICENSE
20
LICENSE
@@ -1,20 +0,0 @@
|
|||||||
Copyright (c) 2011 James Robert, http://jiaaro.com
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of this software and associated documentation files (the
|
|
||||||
"Software"), to deal in the Software without restriction, including
|
|
||||||
without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -1,3 +0,0 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
|
||||||
oid sha256:07d5eec305110cf1dfe1a0c45eed84bc31f889b1b19feab3859a05dc45b70e7b
|
|
||||||
size 33532
|
|
3
pydub-0.23.1.tar.gz
Normal file
3
pydub-0.23.1.tar.gz
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:a5ee51e6bac1e3f64eefd5176aac3299a75e4deec9ad6fef87c3d936f4a034dc
|
||||||
|
size 27180893
|
@@ -1,3 +1,20 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Feb 19 19:14:45 UTC 2019 - Antonio Larrosa <alarrosa@suse.com>
|
||||||
|
|
||||||
|
- Enable tests. Changed source to the github release, which also
|
||||||
|
removes the need to provide a copy of the LICENSE file.
|
||||||
|
- Add 0001-Skip-tests-that-use-unavailable-codecs.patch to skip
|
||||||
|
tests that use codecs not supported by the official ffmpeg package
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Feb 18 10:12:59 UTC 2019 - Antonio Larrosa <alarrosa@suse.com>
|
||||||
|
|
||||||
|
- Update to 0.23.1
|
||||||
|
* Fix bug in passing ffmpeg/avconv parameters for
|
||||||
|
pydub.AudioSegment.from_mp3(), pydub.AudioSegment.from_flv(),
|
||||||
|
pydub.AudioSegment.from_ogg() and pydub.AudioSegment.from_wav()
|
||||||
|
* Fix logic bug in pydub.effects.strip_silence()
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Tue Dec 4 12:52:09 UTC 2018 - Matej Cepl <mcepl@suse.com>
|
Tue Dec 4 12:52:09 UTC 2018 - Matej Cepl <mcepl@suse.com>
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# spec file for package python-pydub
|
# spec file for package python-pydub
|
||||||
#
|
#
|
||||||
# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
|
# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
|
||||||
#
|
#
|
||||||
# All modifications and additions to the file contributed by third parties
|
# All modifications and additions to the file contributed by third parties
|
||||||
# remain the property of their copyright owners, unless otherwise agreed
|
# remain the property of their copyright owners, unless otherwise agreed
|
||||||
@@ -17,24 +17,21 @@
|
|||||||
|
|
||||||
|
|
||||||
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
|
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
|
||||||
# Test data missing
|
|
||||||
%bcond_with test
|
|
||||||
Name: python-pydub
|
Name: python-pydub
|
||||||
Version: 0.23.0
|
Version: 0.23.1
|
||||||
Release: 0
|
Release: 0
|
||||||
Summary: Audio manipulation with Python
|
Summary: Audio manipulation with Python
|
||||||
License: MIT
|
License: MIT
|
||||||
Group: Development/Languages/Python
|
Group: Development/Languages/Python
|
||||||
Url: https://github.com/jiaaro/pydub
|
Url: https://github.com/jiaaro/pydub
|
||||||
Source: https://files.pythonhosted.org/packages/source/p/pydub/pydub-%{version}.tar.gz
|
Source: https://github.com/jiaaro/pydub/archive/v%{version}.tar.gz#/pydub-%{version}.tar.gz
|
||||||
Source10: https://raw.githubusercontent.com/jiaaro/pydub/v%{version}/LICENSE
|
# PATCH-FIX-UPSTREAM
|
||||||
|
Patch0: 0001-Skip-tests-that-use-unavailable-codecs.patch
|
||||||
|
BuildRequires: %{python_module scipy}
|
||||||
BuildRequires: %{python_module setuptools}
|
BuildRequires: %{python_module setuptools}
|
||||||
BuildRequires: fdupes
|
BuildRequires: fdupes
|
||||||
BuildRequires: python-rpm-macros
|
|
||||||
%if %{with test}
|
|
||||||
BuildRequires: %{python_module scipy}
|
|
||||||
BuildRequires: ffmpeg
|
BuildRequires: ffmpeg
|
||||||
%endif
|
BuildRequires: python-rpm-macros
|
||||||
Recommends: python-scipy
|
Recommends: python-scipy
|
||||||
Recommends: python-simpleaudio
|
Recommends: python-simpleaudio
|
||||||
Requires: ffmpeg
|
Requires: ffmpeg
|
||||||
@@ -47,7 +44,7 @@ A Python module to manipulate audio with a high level interface.
|
|||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup -q -n pydub-%{version}
|
%setup -q -n pydub-%{version}
|
||||||
cp %{SOURCE10} .
|
%patch0 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
%python_build
|
%python_build
|
||||||
@@ -56,12 +53,8 @@ cp %{SOURCE10} .
|
|||||||
%python_install
|
%python_install
|
||||||
%python_expand %fdupes %{buildroot}%{$python_sitelib}
|
%python_expand %fdupes %{buildroot}%{$python_sitelib}
|
||||||
|
|
||||||
%if %{with test}
|
|
||||||
%check
|
%check
|
||||||
%{python_expand export PYTHONPATH=%{buildroot}%{$python_sitelib}
|
%python_expand PYTHONPATH=%{buildroot}%{$python_sitelib} $python test/test.py
|
||||||
$python test/test.py
|
|
||||||
}
|
|
||||||
%endif
|
|
||||||
|
|
||||||
%files %{python_files}
|
%files %{python_files}
|
||||||
%license LICENSE
|
%license LICENSE
|
||||||
|
Reference in New Issue
Block a user