diff --git a/av/stream.pyx b/av/stream.pyx index 5a4b5b436ebce1fd1d664faf5a8eeff1af401186..971eaded190405dc11a77a8043941db59f945616 100644 --- a/av/stream.pyx +++ b/av/stream.pyx @@ -1,3 +1,5 @@ +import warnings + from cpython cimport PyWeakref_NewRef from libc.stdint cimport int64_t, uint8_t from libc.string cimport memcpy @@ -13,6 +15,8 @@ from av.utils cimport ( to_avrational ) +from av.deprecation import AVDeprecationWarning + cdef object _cinit_bypass_sentinel = object() @@ -95,6 +99,14 @@ cdef class Stream(object): ) def __getattr__(self, name): + # Deprecate framerate pass-through as it is not always set. + #Â See: https://github.com/PyAV-Org/PyAV/issues/1005 + if self.ptr.codecpar.codec_type == lib.AVMEDIA_TYPE_VIDEO and name in ("framerate", "rate"): + warnings.warn( + "VideoStream.%s is deprecated as it is not always set; please use VideoStream.average_rate." % name, + AVDeprecationWarning + ) + # Convenience getter for codec context properties. if self.codec_context is not None: return getattr(self.codec_context, name) diff --git a/tests/test_file_probing.py b/tests/test_file_probing.py index 29710a1b03dcf3ac2dd7048d94df4f029d73f19a..c67f7fb8ec20915f53178a8b98ebc7d8900d6ce9 100644 --- a/tests/test_file_probing.py +++ b/tests/test_file_probing.py @@ -1,4 +1,5 @@ from fractions import Fraction +import warnings import av @@ -319,6 +320,20 @@ class TestVideoProbe(TestCase): self.assertIn(stream.coded_width, (720, 0)) self.assertIn(stream.coded_height, (576, 0)) + # Deprecated properties. + with warnings.catch_warnings(record=True) as captured: + self.assertIsNone(stream.framerate) + self.assertEqual( + captured[0].message.args[0], + "VideoStream.framerate is deprecated as it is not always set; please use VideoStream.average_rate.", + ) + with warnings.catch_warnings(record=True) as captured: + self.assertIsNone(stream.rate) + self.assertEqual( + captured[0].message.args[0], + "VideoStream.rate is deprecated as it is not always set; please use VideoStream.average_rate.", + ) + class TestVideoProbeCorrupt(TestCase): def setUp(self):