您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

150 行
5.6 KiB

  1. """test_feature_extractors_functional.py -- functional tests for feature extractors
  2. This module contains functional tests for FEs using crafted and/or generated media files
  3. to verify that the FEs are working as expected:
  4. - laughter detection -- uses videos with laughs at known times
  5. - video activity -- uses videos with visual activity at known times
  6. - audio loudness -- uses videos with audio at known times
  7. etc.
  8. These tests are marked slow to avoid running them during normal test runs.
  9. """
  10. import unittest
  11. import pipeline.feature_extractors as extractors
  12. import test.mocks as mocks
  13. class FEFunctionalTest(unittest.TestCase):
  14. """FEFunctionalTest -- base class for functional tests for feature extractors
  15. """
  16. SAMPLE_DIR = "/home/robert/code/softdev2023-24/summerproject/highlights/test/sample_videos"
  17. class TestLaughterFEFunctional(FEFunctionalTest):
  18. """TestLaughterFEFunctional -- functional tests for laughter detection feature extractor"""
  19. def test_laughter_detection(self):
  20. """Test laughter detection feature extractor
  21. Uses:
  22. - sample_videos/sample-manual-audio-laughs-video-colours.mp4
  23. :: laughters at 15-20s
  24. -- pass iff laughter features extracted in this range, *but*
  25. NOTE: LaughFE subtracts from start time to capture what preceded the laughter
  26. so we need to subtract this time (and adds a little after too)
  27. FE 'exposes' these as _PREPEND_TIME and _APPEND_TIME
  28. """
  29. SAMPLE_VIDEO = f"{self.SAMPLE_DIR}/sample-manual-audio-laughs-video-colours.mp4"
  30. START_TIME = 15
  31. END_TIME = 20
  32. # create mock source with the video
  33. source = mocks.MockSource(path=SAMPLE_VIDEO)
  34. # create the feature extractor
  35. testfe = extractors.LaughterFeatureExtractor(input_files=[source])
  36. testfe.setup()
  37. testfe.run()
  38. testfe.teardown()
  39. # check if the feature was extracted:
  40. self.assertTrue(testfe.features)
  41. # check if the feature interval is within the expected range
  42. self.assertTrue(testfe.features[0].interval.start >= (START_TIME - testfe._PREPEND_TIME))
  43. self.assertTrue(testfe.features[0].interval.end <= (END_TIME + testfe._APPEND_TIME))
  44. class TestVideoActivityFEFunctional(FEFunctionalTest):
  45. """TestVisualActivityFEFunctional -- functional tests for visual activity feature extractor
  46. """
  47. def test_visual_activity_functional(self):
  48. """Test visual activity feature extractor
  49. use:
  50. - sample_videos/sample-manual-visualactivity.mp4 :: activity at 15-20s -- pass if activity detected anywhere in this range
  51. """
  52. SAMPLE_VIDEO = f"{self.SAMPLE_DIR}/sample-manual-visualactivity.mp4"
  53. START_TIME = 15
  54. END_TIME = 20
  55. # create mock source with the video
  56. source = mocks.MockSource(path=SAMPLE_VIDEO)
  57. # create the feature extractor
  58. testfe = extractors.VideoActivityFeatureExtractor(input_files=[source])
  59. testfe.setup()
  60. testfe.run()
  61. testfe.teardown()
  62. # check if the feature was extracted:
  63. self.assertTrue(testfe.features)
  64. # check if the feature interval is within the expected range
  65. self.assertTrue(testfe.features[0].interval.start >= START_TIME)
  66. class TestLoudAudioFEFunctional(FEFunctionalTest):
  67. """TestAudioLoudnessFEFunctional -- functional tests for audio loudness feature extractor
  68. """
  69. def test_audio_loudness_functional_one_feature(self):
  70. """Test audio loudness feature extractor
  71. use:
  72. - sample_videos/sample-manual-audio.mp4 :: audio at 15-20s -- pass if audio detected anywhere in this range
  73. -- peak at 16s - 18s, verify this is highest scoring
  74. """
  75. SAMPLE_VIDEO = f"{self.SAMPLE_DIR}/sample-manual-audio.mp4"
  76. START_TIME = 15
  77. END_TIME = 20
  78. PEAK_START = 16
  79. PEAK_END = 18
  80. # create mock source with the video
  81. source = mocks.MockSource(path=SAMPLE_VIDEO)
  82. # create the feature extractor
  83. testfe = extractors.LoudAudioFeatureExtractor(input_files=[source])
  84. testfe.setup()
  85. testfe.run()
  86. testfe.teardown()
  87. # check if the feature was extracted:
  88. self.assertTrue(testfe.features)
  89. # check if the feature interval is within the expected range
  90. self.assertTrue(testfe.features[0].interval.start >= START_TIME)
  91. # get sorted list of features based on feature.score
  92. sorted_features = sorted(testfe.features, key=lambda x: x.score, reverse=True)
  93. # check if the highest scoring feature is within the peak range
  94. self.assertTrue(sorted_features[0].interval.start >= PEAK_START)
  95. def test_audio_loudness_functional_no_features(self):
  96. """Test audio loudness feature extractor using a silent video. This should produce no features
  97. since "-inf" results from pyloudnorm are filtered out by the FE.
  98. Use:
  99. - sample_videos/sample-manual-audio-blank-video-colours.mp4
  100. :: silent video (30s)
  101. -- pass if no features extracted
  102. """
  103. SAMPLE_VIDEO = f"{self.SAMPLE_DIR}/sample-manual-audio-blank-video-colours.mp4"
  104. # create mock source with the video
  105. source = mocks.MockSource(path=SAMPLE_VIDEO)
  106. # create the feature extractor
  107. testfe = extractors.LoudAudioFeatureExtractor(input_files=[source])
  108. testfe.setup()
  109. testfe.run()
  110. testfe.teardown()
  111. # check if the feature was extracted:
  112. self.assertFalse(testfe.features)
  113. if __name__ == "__main__":
  114. unittest.main()