|
25 | 25 | import math |
26 | 26 | import os |
27 | 27 | import random |
| 28 | +import re |
28 | 29 | import zlib |
29 | 30 | from collections import Counter |
30 | 31 | from urllib.parse import quote |
@@ -1654,6 +1655,44 @@ def get_second_level_category_search_url(self): |
1654 | 1655 | else: |
1655 | 1656 | return None |
1656 | 1657 |
|
| 1658 | + def estimate_bpm_from_metadata(self, min_bpm=25, max_bpm=300): |
| 1659 | + """ |
| 1660 | + Estimate the bpm of a sound by looking at its description, tags and name. |
| 1661 | + :param min_bpm: minimum bpm |
| 1662 | + :param max_bpm: maximum bpm |
| 1663 | + :return: estimated bpm (int) or 0 if bpm could not be estimated |
| 1664 | + """ |
| 1665 | + bpm_candidates = list() |
| 1666 | + |
| 1667 | + # Find sequences like 120bpm, bpm120, 120 bpm or bpm 120 in all fields |
| 1668 | + description = self.description.lower() |
| 1669 | + name = self.original_filename.lower() |
| 1670 | + tags = [t.lower() for t in self.get_sound_tags()] |
| 1671 | + for candidate in re.findall(r"\d+[\s]?bpm", description + " " + name + " " + " ".join(tags)) + re.findall( |
| 1672 | + r"bpm[\s]?\d+", description + " " + name + " " + " ".join(tags) |
| 1673 | + ): |
| 1674 | + try: |
| 1675 | + bpm = int(candidate.replace("bpm", "").replace(" ", "")) |
| 1676 | + if min_bpm <= bpm <= max_bpm: |
| 1677 | + bpm_candidates.append(bpm) |
| 1678 | + except ValueError: |
| 1679 | + continue |
| 1680 | + |
| 1681 | + # Find tags corresponding to single numbers and in a range |
| 1682 | + for tag in tags: |
| 1683 | + try: |
| 1684 | + bpm = int(tag) |
| 1685 | + if min_bpm <= bpm <= max_bpm: |
| 1686 | + bpm_candidates.append(bpm) |
| 1687 | + except ValueError: |
| 1688 | + continue |
| 1689 | + |
| 1690 | + if not bpm_candidates: |
| 1691 | + return 0 |
| 1692 | + |
| 1693 | + # Return the most common candidate |
| 1694 | + return Counter(bpm_candidates).most_common(1)[0][0] |
| 1695 | + |
1657 | 1696 | class Meta: |
1658 | 1697 | ordering = ("-created",) |
1659 | 1698 | indexes = [ |
|
0 commit comments