示例#1
0
    def setmusiclength(self):
        #important function on a player (also hard to do)
        if self.currentsong.endswith('.mp3') == True:
            self.song = MP3(self.currentsong)
            self.songinfo = ID3(self.currentsong)
            self.songlength = self.song.info.length
            self.songround = round(self.songlength)
            self.songmins, self.songsecs = divmod(self.songround, 60)
            self.songmins = str(self.songmins).zfill(2)
            self.songsecs = str(self.songsecs).zfill(2)
            self.progress_label_2.config(text=str(self.songmins) + ':' +
                                         str(self.songsecs))

            try:
                self.songname.config(text=self.songinfo['TIT2'].text[0])
                self.artistname.config(text=self.songinfo['TPE1'].text[0])
                self.albumname.config(text=self.songinfo['TALB'].text[0])
            except:
                self.songname.config(text=self.currentsong)
                self.artistname.config(text='failed to read metadata')
                self.albumname.config(text='failed to read metadata')

        if self.currentsong.endswith('.flac') == True:
            self.song = FLAC(self.currentsong)
            self.songlength = self.song.info.length
            self.songround = round(self.songlength)
            self.songmins, self.songsecs = divmod(self.songround, 60)
            self.songmins = str(self.songmins).zfill(2)
            self.songsecs = str(self.songsecs).zfill(2)
            self.progress_label_2.config(text=str(self.songmins) + ':' +
                                         str(self.songsecs))
            self.music_player_scale.config(from_=0, to=self.songlength)

            try:
                self.songname.config(text=self.song['TITLE'])
                self.artistname.config(text=self.song['ARTIST'])
                self.albumname.config(text=self.song['ALBUM'])
            except:
                self.songname.config(text=self.currentsong)
                self.artistname.config(text='failed to read metadata')
                self.albumname.config(text='failed to read metadata')

        if self.currentsong.endswith('.ogg') == True:
            self.song = WAVE(self.currentsong)
            self.songlength = self.song.info.length
            self.songround = round(self.songlength)
            self.songmins, self.songsecs = divmod(self.songround, 60)
            self.songsecs = str(self.songsecs).zfill(2)
            self.progress_label_2.config(text=str(self.songmins) + ':' +
                                         str(self.songsecs))
示例#2
0
 def __init__(self, fileLocation):
     self.musicLocation = fileLocation
     try:
         self.musicLength = floor(MP3(self.musicLocation).info.length)
     except:
         self.musicLength = floor(WAVE(self.musicLocation).info.length)
     self.musicTitle = Path(self.musicLocation).name
示例#3
0
 def _process_audio_file(self, file_path: str, format_name: str):
     if format_name == "mp3":
         audio = MP3(file_path)
     elif format_name == "wav":
         audio = WAVE(file_path)
     self.duration = float(audio.info.length)
     self.size = float(os.stat(file_path).st_size)
示例#4
0
    def test_save_tags(self):
        from mutagen.id3 import TIT1
        tags = self.tmp_wav_pcm_2s_16000_08_ID3v23.tags
        tags.add(TIT1(encoding=3, text="foobar"))
        tags.save()

        new = WAVE(self.tmp_wav_pcm_2s_16000_08_ID3v23.filename)
        self.failUnlessEqual(new["TIT1"], ["foobar"])
示例#5
0
 def test_picard_lifecycle(self):
     path_tmp_wav_file = \
         get_temp_copy(self.fn_wav_pcm_2s_16000_08_notags)
     from mutagen.id3 import ID3
     wav = WAVE(path_tmp_wav_file)
     id3 = wav.tags
     """" Picard WaveFile._get_tags: """
     self.assertIsNone(id3, "Ensure ID3-tag-header does not exist")
     """" Picard WaveFile._get_tags: initialize tags """
     wav.add_tags()
     id3 = wav.tags
     self.assertIsInstance(id3, ID3)
     """ ID3v2.3 separator """
     separator = '/'
     """ Initialize Picard like metadata tags """
     self.__init_id3_tags(id3, major=3)
     """ Write the Picard like metadata to the empty WAVE-file """
     id3.save(path_tmp_wav_file, v23_sep=separator)
     """ Tags (metadata) have been added; now load the file again """
     wav = WAVE(path_tmp_wav_file)
     id3 = wav.tags
     self.assertIsInstance(id3, ID3)
     self.assertEquals(id3["TRCK"], "1/10")
     self.assertEquals(id3["TPOS"], "1/1")
     self.assertEquals(id3["TXXX:MusicBrainz Release Group Id"],
                       "e00305af-1c72-469b-9a7c-6dc665ca9adc")
     self.assertEquals(id3["TXXX:MusicBrainz Album Artist Id"], [
         "3fe817fc-966e-4ece-b00a-76be43e7e73c",
         "984f8239-8fe1-4683-9c54-10ffb14439e9"
     ])
     self.assertEquals(id3["TXXX:CATALOGNUMBER"], ["PRAR931391"])
     self.assertEquals(id3["TSRC"], ["NLB931100460", "USMH51100098"])
示例#6
0
        def load():
            if self.fileType == "mp3":
                self.raw = MP3(self.filePath)
            elif self.fileType == "wav":
                self.raw = WAVE(self.filePath)
            self.info = self.raw.info
            self.ok = True
            # we've got all required info, lets try to grab some more complex data
            self.tags = ID3(self.filePath)
            art_frames = self.tags.getall("APIC")
            art = [add_frame_to_cache(frame) for frame in art_frames]

            if len(art):
                self.art = art
def get_audio_file_duration(file_path: str) -> float:
    _, ext = os.path.splitext(file_path)

    if ext not in [".mp3", ".wav"]:
        raise ValueError("Unsupported file format: %s (%s)" % (ext, file_path))

    if ext == ".mp3":
        mp3 = MP3(file_path)
        duration = mp3.info.length
    elif ext == ".wav":
        wav = WAVE(file_path)
        duration = wav.info.length

    return duration
    def _play_wav(self, file_path: str) -> None:
        if not shutil.which("aplay"):
            raise Exception(
                'Unable to find "aplay" binary. Make sure it\'s installed on the ' "system."
            )

        wav = WAVE(file_path)
        duration = wav.info.length

        LOG.trace('Playing audio file "%s"' % (file_path), duration=duration)

        args = "aplay -q %s" % (shlex.quote(file_path))
        # NOTE: We set preexec_fn since we want child process to also be killed if the parent is
        # killed
        subprocess.run(args, shell=True, check=True, preexec_fn=on_parent_exit("SIGTERM"))
示例#9
0
def audioFile(audio):
    aud_str = str(audio)
    if aud_str.endswith(".mp3"):
        aud1 = MP3(audio)
        len1 = aud1.info.length
        return int(len1)
    elif aud_str.endswith('.wav'):
        aud2 = WAVE(audio)
        len2 = aud2.info.length
        return int(len2)
    elif aud_str.endswith('.flac'):
        aud3 = FLAC(audio)
        len3 = aud3.info.length
        return int(len3)
    elif aud_str.endswith('.aac'):
        aud4 = AAC(audio)
        len4 = aud4.info.length
        return int(len4)
    elif aud_str.endswith('.ac3'):
        aud5 = AC3(audio)
        len5 = aud5.info.length
        return int(len5)
    elif aud_str.endswith('.aiff'):
        aud6 = AIFF(audio)
        len6 = aud6.info.length
        return int(len6)
    elif aud_str.endswith('.asf'):
        aud7 = ASF(audio)
        len7 = aud7.info.length
        return int(len7)
    elif aud_str.endswith('.dsf'):
        aud8 = DSF(audio)
        len8 = aud8.info.length
        return int(len8)
    elif aud_str.endswith('.mp4'):
        aud9 = MP4(audio)
        len9 = aud9.info.length
        return int(len9)
    elif aud_str.endswith('.smf'):
        aud10 = SMF(audio)
        len10 = aud10.info.length
        return int(len10)
    elif aud_str.endswith('.ogg'):
        aud12 = OggFileType(audio)
        len12 = aud12.info.length
        return int(len12)
    else:
        return str("File type not supported.")
示例#10
0
 def run(self):
     if self.audioname != "none":
         pygame.mixer.music.load(self.audioname)
         if self.audioname[-3:] == "mp3":
             self.song = MP3(self.audioname)
         elif self.audioname[-3:] == "wav":
             self.song = WAVE(self.audioname)
         elif self.audioname[-3:] == "ogg":
             self.song = OggFileType(self.audioname)  #not tested
         self.songLength = self.song.info.length
         if self.pushtotalk:
             self.c.press(self.pushkey)
         pygame.mixer.music.play()
         while self.running == True and pygame.mixer.music.get_busy(
         ) == True:
             time.sleep(0.5)
             pass
         if self.pushtotalk:
             self.c.release(self.pushkey)
示例#11
0
async def on_voice_state_update(user, before, after):
    val = random.randint(1, 8)
    if val == 2:
        if after.channel is not None and before.channel is None and user.id != 665024859918696509:
            print("you win!!!")
            print(f"{user} joined {after.channel}")

            wait_time = random.randint(1, 30)
            print(f"waiting {wait_time}")
            time.sleep(wait_time)
            vc = await after.channel.connect()
            time.sleep(1)
            peez_list = os.listdir("./peezy_mp3")
            clip = peez_list[random.randint(0, len(peez_list) - 1)]
            audio = WAVE(f"./peezy_mp3/{clip}")
            vc.play(discord.FFmpegPCMAudio(f"./peezy_mp3/{clip}"))
            time.sleep(audio.info.length)
            for x in client.voice_clients:
                await x.disconnect()
            print("Done")
def checkFileValidity(filename, directory, format):
    audio = ""
    if format == "FLAC":
        try:
            audio = FLAC(str(directory) + "/" + str(filename))
        except:
            messagebox.showinfo("Error", "Invalid or Corrupt File")
            return "Invalid or corrupt file\n"
    elif format == "AIFF":
        try:
            audio = AIFF(str(directory) + "/" + str(filename))
        except:
            messagebox.showinfo("Error", "Invalid or Corrupt File")
            return "Invalid or corrupt file\n"
    elif format == "MP3":
        try:
            audio = MP3(str(directory) + "/" + str(filename))
        except:
            messagebox.showinfo("Error", "Invalid or Corrupt File")
            return "Invalid or corrupt file\n"
    elif format == "OGG":
        try:
            audio = OggVorbis(str(directory) + "/" + str(filename))
        except:
            messagebox.showinfo("Error", "Invalid or Corrupt File")
            return "Invalid or corrupt file\n"
    elif format == "WAV":
        try:
            audio = WAVE(str(directory) + "/" + str(filename))
        except:
            messagebox.showinfo("Error", "Invalid or Corrupt File")
            return "Invalid or corrupt file\n"
    elif format == "M4A":
        # M4A is deprecated in mutagen, MP4 is suggested instead
        try:
            audio = MP4(str(directory) + "/" + str(filename))
        except:
            messagebox.showinfo("Error", "Invalid or Corrupt File")
            return "Invalid or corrupt file\n"
    return audio
示例#13
0
    def setUp(self):
        fn_wav_pcm_2s_16000_08_id3v23 = \
            os.path.join(DATA_DIR, "silence-2s-PCM-16000-08-ID3v23.wav")
        self.wav_pcm_2s_16000_08_ID3v23 = \
            WAVE(fn_wav_pcm_2s_16000_08_id3v23)

        self.tmp_fn_pcm_2s_16000_08_ID3v23 = \
            get_temp_copy(fn_wav_pcm_2s_16000_08_id3v23)
        self.tmp_wav_pcm_2s_16000_08_ID3v23 = \
            WAVE(self.tmp_fn_pcm_2s_16000_08_ID3v23)

        self.fn_wav_pcm_2s_16000_08_notags = \
            os.path.join(DATA_DIR, "silence-2s-PCM-16000-08-notags.wav")
        self.wav_pcm_2s_16000_08_notags = \
            WAVE(self.fn_wav_pcm_2s_16000_08_notags)

        self.tmp_fn_pcm_2s_16000_08_notag = \
            get_temp_copy(self.fn_wav_pcm_2s_16000_08_notags)
        self.tmp_wav_pcm_2s_16000_08_notag = \
            WAVE(self.tmp_fn_pcm_2s_16000_08_notag)

        fn_wav_pcm_2s_44100_16_id3v23 = \
            os.path.join(DATA_DIR, "silence-2s-PCM-44100-16-ID3v23.wav")
        self.wav_pcm_2s_44100_16_ID3v23 = WAVE(fn_wav_pcm_2s_44100_16_id3v23)
示例#14
0
文件: main.py 项目: mgrkan/RRAYC
                 "Started new video, {} id: {}".format(post_title, post.id))
    except:
        pass
    submission_id = post.id
    vidname = post.id
    submission = reddit.submission(submission_id)
    text_to_wav("en-US-Wavenet-B", submission.title, "1post")
    print(" - post text converted to wav - ")
    screenshotter.createPostSS(submission.title,
                               sub_input, subIcon, upImage, downImage,
                               str(submission.ups), submission.author)
    print(" - created post ss - ")
    imgdir = pathlib.Path(SAMPLE_INPUTS + '/imgs/1post')
    path = os.path.join(SAMPLE_INPUTS, "audio")
    file = os.path.join(path, "1post.wav")
    aud = WAVE(file)
    audio_info = aud.info
    duration = int(audio_info.length)
    output_video = os.path.join(SAMPLE_OUTPUTS, "1post_output.mp4")
    video_creator.makeVideo(imgdir, file, output_video, duration)
    submissionList = []
    submission.comments.replace_more(limit=10)

    comments = submission.comments.list()
    commentCounter = 0
    timeCounter = 0.0

    avatar = submission.author.icon_img
    response = requests.get(avatar)
    file = open(pathlib.Path(RESOURCES + "/images/avatar.png"), "wb")
    file.write(response.content)
示例#15
0
def main():
    op = OptionParser(usage=__doc__)
    op.add_option("--folder", help="name of the folder to process")
    op.add_option("--catno", help="release catalogue number to search by")
    op.add_option("--id", help="Discogs release code to search by")
    op.add_option("--list", help="list versions of the release and exit")
    op.add_option("--debug", help="print out the details for debugging")
    opts, args = op.parse_args()

    if opts.debug:
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig(level=logging.WARNING)

    tracklist = []
    bitrates = []
    file_counter = 0
    total_duration = 0
    image_counter = 0
    fetched_release_info = {}
    folder_name_pattern = {}
    results = None
    calculated_duration = (0, 0, 0)
    calculated_duration_from_audio = (0, 0, 0)

    release_info = re.split(r'[^a-zA-Z\d\s:\!\.\']', opts.folder)
    release_info = filter(None, release_info)
    artist = next(release_info).strip()
    album = next(release_info).strip().title()

    if opts.list:
        list_results = d.search(album, artist=artist, type='release')
        for i in range(list_results.count):
            print_release_version(list_results[i])
        sys.exit()

    folder_files = sorted(os.listdir(opts.folder))
    audio_files, files_count, sample_file_1, sample_file_2 = filter_files(
        folder_files)
    print(f"audio files found:      {files_count}")
    # ==========================================================================
    logger.debug(f"\n    >>> parsed artist: {artist}")
    logger.debug(f"\n    >>> parsed album: {album}")
    logger.debug(f"\n    >>> folder files: {folder_files}")
    logger.debug(f"\n    >>> audio files: {audio_files}")
    logger.debug(f"\n    >>> sample file 1: {sample_file_1}")
    logger.debug(f"\n    >>> sample file 2: {sample_file_2}")
    # ==========================================================================
    
    if opts.id:
        fetched_release_info["id"] = opts.id
        release = d.release(opts.id)
        prepared_tracks = [
            track for track in release.tracklist if track.position \
                or len(track.data.get('sub_tracks', [])) > 0
        ]

        # Handle a rare case of mash-up tracks on mixed compilations
        # listed without durations
        any_duration_absent = any(
            len(track.duration) < 1 for track in prepared_tracks)
        if any_duration_absent and files_count != len(prepared_tracks):
            prepared_tracks = [
                track for track in prepared_tracks if track.duration]

        fetched_release_info["artist"] = release.artists[0].name
        fetched_release_info["tracklist"] = [
            track.title for track in prepared_tracks]
        fetched_release_info["year"] = release.year
        total_artists = len(
            set(track.artists[0].name for track in prepared_tracks))
        multiple_track_artists = any(
            len(track.artists) > 1 for track in prepared_tracks)
        if multiple_track_artists or total_artists > 1:
            fetched_release_info["various"] = True

    if opts.catno:
        results = d.search(opts.catno, type='release')

    if not opts.catno and not opts.id:
        results = d.search(album, artist=artist, type='release')

    if results:
        print(f"release versions found: {results.count}")
        for i in range(results.count):
            prepared_tracks = [
                track for track in results[i].tracklist if track.position \
                    or len(track.data.get('sub_tracks', [])) > 0 \
                    and not re.search('[b-zB-Z]', track.position)
            ]
            if len(prepared_tracks) == files_count:
                picked_id = pick_release_format_id(results[i])
                first_track = prepare_track_title(prepared_tracks[0].title)
                last_track = prepare_track_title(prepared_tracks[-1].title)
                first_titles = list(
                    set(first_track.split()) & set(sample_file_1.split()))
                last_titles = list(
                    set(last_track.split()) & set(sample_file_2.split()))
                # ==============================================================
                logger.debug(f"\n    >>>>>> resulted title: {results[i].title}")
                logger.debug("\n    >>>>>> resulted catalogue number: "
                    f"{results[i].data['catno']}")
                logger.debug("\n    >>>>>> format name: "
                    f"{results[i].formats[0].get('name')}")
                logger.debug("\n    >>>>>> format descriptions: "
                    f"{results[i].formats[0].get('descriptions')}")
                logger.debug(f"\n    >>>>>> picked release ID: {picked_id}")
                logger.debug(f"\n    >>>>>> first track: {first_track}")
                logger.debug("\n    >>>>>> first track split: "
                    f"{first_track.split()}")
                logger.debug(f"\n    >>>>>> last track: {last_track}")
                logger.debug("\n    >>>>>> last track split: "
                    f"{last_track.split()}")
                logger.debug(f"\n    >>>>>> sample file 1: {sample_file_1}")
                logger.debug("\n    >>>>>> sample file 1 split: "
                    f"{sample_file_1.split()}")
                logger.debug(f"\n    >>>>>> sample file 2: {sample_file_2}")
                logger.debug("\n    >>>>>> sample file 2 split: "
                    f"{sample_file_2.split()}")
                logger.debug(f"\n    >>>>>> first titles: {first_titles}")
                logger.debug(f"\n    >>>>>> last titles: {last_titles}")
                # ==============================================================
                if len(first_titles) > 1 and len(last_titles) > 1:
                    fetched_release_info["id"] = picked_id \
                        if results[i].id == picked_id else None
                    fetched_release_info["artist"] = results[i].artists[0].name
                    fetched_release_info["tracklist"] = [
                        track.title for track in prepared_tracks]
                    fetched_release_info["year"] = results[i].year
                    fetched_release_info["various"] = False
                    release = d.release(fetched_release_info["id"])
                    # ==========================================================
                    logger.debug("\n    >>>>>>>>> release ID: "
                        f"{fetched_release_info['id']}")
                    # ==========================================================
                    if fetched_release_info["artist"] == 'Various':
                        fetched_release_info["artists"] = [
                            re.sub(r"\(\d+\)", '',
                            track.artists[0].name).strip() \
                                for track in results[i].tracklist \
                                if track.position
                        ]
                        # ======================================================
                        logger.debug("\n    >>>>>>>>> artists: "
                            f"{fetched_release_info['artists']}")
                        # ======================================================
                        fetched_release_info["various"] = True
                    if fetched_release_info["id"]:
                        break

    # ==========================================================================
    logger.debug(f"\n    >>> release: {release}")
    logger.debug(f"\n    >>> fetched release ID: {fetched_release_info['id']}")
    logger.debug(f"\n    >>> fetched format: "
        f"{release.formats[0].get('descriptions')}")
    # ==========================================================================
    
    # Process images
    if release.images:
        for image in release.images:
            image_counter += 1
            f = open(os.path.join(opts.folder, '{}-{:02}.jpg'.format(
                fetched_release_info["id"], image_counter)),'wb')
            f.write(requests.get(image["resource_url"]).content)
            f.close()
        main_image = os.path.join(opts.folder,
            '{}-01.jpg'.format(fetched_release_info["id"]))
        main_image_size = Image.open(main_image).size if os.path.exists(
            main_image) else (0, 0)
        folder_image = os.path.join(opts.folder, 'folder.jpg')
        folder_image_size = Image.open(folder_image).size if os.path.exists(
            folder_image) else (0, 0)
        cover_image = os.path.join(opts.folder, 'cover.jpg')
        cover_image_size = Image.open(cover_image).size if os.path.exists(
            cover_image) else (0, 0)
        image_sizes = {
            "main": main_image_size[0],
            "folder": folder_image_size[0],
            "cover": cover_image_size[0]
        }
        chosen_image = None
        for k, v in image_sizes.items():
            if v in range(450, 650):
                if k == "main":
                    chosen_image = main_image
                elif k == "folder":
                    chosen_image = folder_image
                elif k == "cover":
                    chosen_image = cover_image
        if chosen_image:
            # ==================================================================
            logger.debug(f"\n    >>>>>> chosen image: {chosen_image}")
            logger.debug("\n    >>>>>> chosen image size: "
                f"{Image.open(chosen_image).size}")
            # ==================================================================
            try:
                shutil.copyfile(
                    os.path.join(chosen_image),
                    os.path.join(folder_image))
            except shutil.SameFileError:
                pass
        else:
            try:
                shutil.copyfile(
                    os.path.join(opts.folder,
                        '{}-01.jpg'.format(fetched_release_info["id"])),
                    os.path.join(folder_image))
            except shutil.SameFileError:
                pass
    print(f"fetched artist:         {fetched_release_info['artist']}")
    print(f"fetched tracklist:      {fetched_release_info['tracklist']}")
    print(f"fetched year:           {fetched_release_info['year']}")
    release_date = release.data["released"].replace("-", ".")
    catalogue_number = release.data["labels"][0]["catno"].replace("/", "_")
    if catalogue_number == "none":
        catalogue_number = ""
    print(f"catalogue number:         {catalogue_number}")

    # Collect release options
    folder_name_pattern["type"] = ""

    for media_format in release.formats:
        if media_format["qty"] > "1":
            if media_format["name"] in physical_media_formats:
                folder_name_pattern["type"] += "{}{}, ".format(
                    media_format["qty"], media_format["name"])
            if media_format["name"] == "Vinyl" and "LP" in \
                media_format["descriptions"]:
                    folder_name_pattern["type"] += f"{media_format['qty']}LP, "
                    media_format["descriptions"].remove("LP")

        cleansed_descriptions = sanitize_descriptions(media_format)
        media_format_name = media_format["name"] if media_format["name"] not in \
            physical_media_formats else ""
        
        if media_format_name:
            folder_name_pattern["type"] += f"{media_format_name}, "
        if cleansed_descriptions:
            folder_name_pattern["type"] += ", ".join(cleansed_descriptions)
            folder_name_pattern["type"] += ", "
            
    if fnmatch.filter(os.listdir(opts.folder), '*.nfo'):
        folder_name_pattern["type"] += "scene, "
    # ==========================================================================
    logger.debug(f"\n    >>> folder name pattern: {folder_name_pattern}")
    # ==========================================================================
    release_title_raw = string.capwords(release.title.strip()).title()
    release_title = release_title_raw.replace("?", "_").replace(":", " -") \
        .replace("/", "-")
    type_descriptions = (str(folder_name_pattern["type"]).lower() \
        .replace("\"", "''") if "type" in folder_name_pattern.keys() else "")
    type_descriptions = re.sub(r'ep(?!\w+)', 'EP', type_descriptions)
    type_descriptions = re.sub(r'lp(?!\w+)', 'LP', type_descriptions)
    type_descriptions = re.sub(r'cd(?!\w+)', 'CD', type_descriptions)

    type_descriptions_for_tags = [i.strip() \
        for i in type_descriptions.split(',') if i]
    descriptions_for_tags_found = [i for i in descriptions_for_tags \
        if i in type_descriptions_for_tags]
    if fetched_release_info["artist"] == 'Various':
        type_descriptions = re.sub('compilation', '', type_descriptions)
        # If there's a stray comma in the descriptions, remove it
        type_descriptions = re.sub(r'\s,', '', type_descriptions)
        album_title_for_tags = "V/A: {title} [{type}]".format(
            title=release.title.strip(), type=type_descriptions.strip(', ')) \
            if descriptions_for_tags_found else f"V/A: {release.title.strip()}"
    else:
        album_title_for_tags = "{title} [{type}]".format(
                title=release.title.strip(),
                type=", ".join(descriptions_for_tags_found)
            ) if descriptions_for_tags_found else release.title.strip()
    # ==========================================================================
    logger.debug(f"\n    >>> release title: {release_title}")
    logger.debug(f"\n    >>> album title for tags: {album_title_for_tags}")
    logger.debug(f"\n    >>> type descriptions: {type_descriptions}")
    # ==========================================================================

    # Process audio files
    for audio_file in audio_files:
        is_writeable = os.access(os.path.join(opts.folder, audio_file), os.W_OK)
        if not is_writeable:
            os.chmod(os.path.join(opts.folder, audio_file), stat.S_IWRITE)
        file_extension = os.path.splitext(audio_file)[-1].lower()[1:]
        track_title, track_artist, track_position, multiple_discs = prepare_tags(
            prepared_tracks, file_counter, fetched_release_info)
        track_position_for_tags = track_position.split('-')[1] \
            if multiple_discs else track_position
        if not track_position_for_tags.isdigit():
            track_position_for_tags = str(file_counter+1)
        disc_number = track_position.split('-')[0] if multiple_discs else ""
        if disc_number:
            album_title_for_tags = re.sub(
                r'\d?CD\d?', f'CD{disc_number}', album_title_for_tags)
        albumart = os.path.join(opts.folder, 'folder.jpg')
        # ==================================================================
        logger.debug(f"\n    >>>>>> audio file: {audio_file}")
        logger.debug(f"\n    >>>>>> file extension: {file_extension}")
        logger.debug(f"\n    >>>>>> tag track: {track_title}")
        logger.debug(f"\n    >>>>>> tag artist: {track_artist}")
        logger.debug(f"\n    >>>>>> track position: {track_position}")
        logger.debug(f"\n    >>>>>> disc number: {disc_number}")
        logger.debug(f"\n    >>>>>> is writeable: {is_writeable}")
        logger.debug(f"\n    >>>>>> album art: {albumart}")
        # ==================================================================

        if file_extension == "mp3":            
            audio = MP3(os.path.join(opts.folder, audio_file))
            audio.tags['TIT2'] = TIT2(encoding=3, text=track_title)
            audio.tags['TPE1'] = TPE1(encoding=3, text=track_artist)
            audio.tags['TALB'] = TALB(encoding=3, text=album_title_for_tags)
            audio.tags['TDRC'] = TDRC(encoding=3,
                text=str(fetched_release_info["year"]))
            audio.tags['TRCK'] = TRCK(encoding=3, text=track_position_for_tags)
            audio.tags.update()

            # Get bitrate information
            fetched_release_info["bitrate_mode"] = str(audio.info.bitrate_mode)
            bitrates.append(audio.info.bitrate)
            total_duration += audio.info.length
            # ==================================================================
            logger.debug("\n    >>>>>>>>> bitrate mode: "
                f"{fetched_release_info['bitrate_mode']}")
            logger.debug(f"\n    >>>>>>>>> bitrates: {bitrates}")
            # ==================================================================

            # Embed the artwork
            if os.path.isfile(albumart):
                # ==============================================================
                logger.debug(f"\n    >>>>>>>>>>>> album art in mp3: {albumart}")
                # ==============================================================
                image = Picture()
                mime = 'image/jpeg'
                with open(albumart, 'rb') as f:
                    image.data = f.read()
                audio.tags['APIC:'] = APIC(encoding=3, mime=mime, type=3,
                    desc=u'front cover', data=image.data)
            audio.save()
        elif file_extension == "flac":
            audio = FLAC(os.path.join(opts.folder, audio_file))
            audio["title"] = track_title
            audio["artist"] = track_artist
            audio["album"] = album_title_for_tags

            # Get bitrate information
            file_bitrate = (audio.info.bits_per_sample \
                * audio.info.total_samples) / audio.info.length
            bitrates.append(file_bitrate)
            fetched_release_info["bitrate_mode"] = "BitrateMode.VBR"
            total_duration += audio.info.length
            # ==================================================================
            logger.debug(f"\n    >>>>>>>>> bitrates: {bitrates}")
            logger.debug(f"\n    >>>>>>>>> embedded pictures: {audio.pictures}")
            # ==================================================================
            if not audio.pictures:
                # ==============================================================
                logger.debug(f"\n    >>>>>>>>>>>> album art in flac: {albumart}")
                # ==============================================================
                if os.path.isfile(albumart):
                    image = Picture()
                    with open(albumart, 'rb') as f:
                        image.data = f.read()
                    image.mime = 'image/jpeg'
                    image.type = PictureType.COVER_FRONT
                    image.width = 500
                    image.height = 500
                    audio.add_picture(image)
            audio.save()
            # ==================================================================
            logger.debug(
                f"\n    >>>>>>>>> embedded pictures after save: {audio.pictures}")
            # ==================================================================
        elif file_extension == "m4a":
            audio = MP4(os.path.join(opts.folder, audio_file))
            audio.tags['\xa9nam'] = [track_title]
            audio.tags['\xa9ART'] = [track_artist]
            audio.tags['aART']    = [track_artist]
            audio.tags['\xa9alb'] = [album_title_for_tags]
            audio.tags.update()
            audio.save()
            bitrates.append(audio.info.bitrate)
            # ==================================================================
            logger.debug(f"\n    >>>>>>>>> bitrates: {bitrates}")
            # ==================================================================
            fetched_release_info["bitrate_mode"] = "BitrateMode.CBR"
            total_duration += audio.info.length
        elif file_extension == "wav":
            audio = WAVE(os.path.join(opts.folder, audio_file))
            # Create ID3 tag if not present
            if not audio.tags:
                audio.add_tags()
            audio.tags['TIT2'] = TIT2(encoding=3, text=track_title)
            audio.tags['TPE1'] = TPE1(encoding=3, text=track_artist)
            audio.tags['TALB'] = TALB(encoding=3, text=album_title_for_tags)
            audio.tags['TDRC'] = TDRC(encoding=3,
                text=str(fetched_release_info["year"]))
            audio.tags['TRCK'] = TRCK(encoding=3, text=track_position_for_tags)
            if 'APIC:' not in audio.tags.keys():
                # ==============================================================
                logger.debug(f"\n    >>>>>>>>> album art in wav: {albumart}")
                # ==============================================================
                if os.path.isfile(albumart):
                    image = Picture()
                    with open(albumart, 'rb') as f:
                        image.data = f.read()
                    # ==========================================================
                    logger.debug(
                        f"\n    >>>>>>>>>>>> image mime in wav: {image.mime}")
                    # ==========================================================
                    mime = 'image/jpeg'
                    audio.tags['APIC:'] = APIC(encoding=3, mime=mime, type=3,
                        desc=u'front cover', data=image.data)
            audio.tags.update()
            audio.save()
            bitrates.append(1411200)
            # ==================================================================
            logger.debug(f"\n    >>>>>>>>> bitrates: {bitrates}")
            # ==================================================================
            fetched_release_info["bitrate_mode"] = "BitrateMode.CBR"
            total_duration += audio.info.length
        fetched_release_info["bitrate_kbps"] = int(audio.info.bitrate / 1000)
        fetched_release_info["sample_rate"] = audio.info.sample_rate
        fetched_release_info["bits_per_sample"] = audio.info.bits_per_sample \
            if hasattr(audio.info, 'bits_per_sample') else "no data"
        fetched_release_info["channels"] = audio.info.channels
        rename_files(
            opts, audio_file, file_counter, fetched_release_info,
            multiple_discs, track_artist, track_position, track_title,
            file_extension
        )
        file_counter += 1
        # ==================================================================
        logger.debug(f"\n    >>>>>> total duration: {total_duration}")
        # ==================================================================
    print(f"tracks processed:       {file_counter}")
    average_bitrate = int(sum(bitrates) / len(bitrates))
    print(f"average bitrate (bps):  {average_bitrate}")
    calculated_duration_from_audio = calculate_durations(total_duration)
    
    # Choose a bitrate mode descriptor
    if fetched_release_info["bitrate_mode"] in [
            "BitrateMode.CBR", "BitrateMode.UNKNOWN"]:
        if average_bitrate in range(319700, 320200):
            folder_name_pattern["media"] = "320"
        elif average_bitrate in range(256000, 256200):
            folder_name_pattern["media"] = "256"
        elif average_bitrate in range(224000, 224200):
            folder_name_pattern["media"] = "224"
        elif average_bitrate in range(192000, 192200):
            folder_name_pattern["media"] = "192"
        elif average_bitrate in range(160000, 160200):
            folder_name_pattern["media"] = "160"
        elif average_bitrate in range(128000, 128200):
            folder_name_pattern["media"] = "128"
        elif average_bitrate in range(1300000, 1500000):
            folder_name_pattern["media"] = "WAV"
        else:
            folder_name_pattern["media"] = "_".join(
                str(i)[:3] for i in set(bitrates))
    elif fetched_release_info["bitrate_mode"] == "BitrateMode.VBR":
        if average_bitrate in range(700000, 1200000):
            folder_name_pattern["media"] = "FLAC"    
        else:
            folder_name_pattern["media"] = "VBR"
    elif fetched_release_info["bitrate_mode"] == "BitrateMode.ABR":
        folder_name_pattern["media"] = "ABR"

    # Apply the new folder name pattern
    new_folder_name = "{year} {title} [{type}{catno}] @{media}".format(
        year=release_date,
        title=strip_accents(release_title),
        type=type_descriptions if catalogue_number \
            else type_descriptions.strip(', '),
        catno=str(catalogue_number).upper(),
        media=folder_name_pattern["media"]
    )
    os.rename(opts.folder, new_folder_name)
    calculated_duration = calculate_durations(0, release=release)
    
    # Print release details
    print(f"processed release title: {new_folder_name}\n")
    for track in prepared_tracks:
        print(f"{track.position} {track.title} {track.duration}")
    print("============ total duration (h:m:s): ",
        f"{calculated_duration[0]:02d}:{calculated_duration[1]:02d}"
        f":{calculated_duration[2]:02d}")
    print("==== total duration [audio] (h:m:s): ",
        f"{calculated_duration_from_audio[0]:02d}:"
        f"{calculated_duration_from_audio[1]:02d}:"
        f"{calculated_duration_from_audio[2]:02d}")
    print("================== folder size (Mb): ", "{:.2f}".format(
        float(get_folder_size(new_folder_name)) / 1000000.0).replace(".", ","))
    print("\n================== sample rate (Hz): ",
        fetched_release_info["sample_rate"] \
        if "sample_rate" in fetched_release_info.keys() else "no data")
    print("================== bit depth (bits): ",
        fetched_release_info["bits_per_sample"] \
        if "bits_per_sample" in fetched_release_info.keys() else "no data")
    print("==================== bitrate (kbps): ",
        fetched_release_info["bitrate_kbps"] \
        if "bitrate_kbps" in fetched_release_info.keys() else "no data")
    print("========================== channels: ",
        fetched_release_info["channels"] \
        if "channels" in fetched_release_info.keys() else "no data")
示例#16
0
文件: funcs.py 项目: amsynist/sampler
def audio_length(aud_file):
    audio = WAVE(aud_file)
    length = int(audio.info.length)
    print(length)
示例#17
0
class MusicPlayer(ThemedTk):
    def __init__(self, *args, **kwargs):

        #pre-variable initialization
        self.versionname = 'Pytone v1.5b'

        #initialization
        super(MusicPlayer, self).__init__(theme='equilux')
        pygame.init()
        mixer.init()
        MUSIC_END = pygame.USEREVENT + 1
        pygame.mixer.music.set_endevent(MUSIC_END)
        self.automusicslider = threading.Thread(target=self.musicsliderplace)
        self.musicloop = threading.Thread(target=self.loopsong)

        #window layout initialization
        self.resizable(False, False)
        self.title(self.versionname)  #1.3 release
        self.configure(background='grey22')
        self.geometry('1000x600')
        self.iconbitmap('icon.ico')
        self.protocol("WM_DELETE_WINDOW", self.ask_quit)

        self.style = ttk.Style()
        self.style.configure('TButton', background='grey22')
        self.style.configure('TScale', background='grey22')

        #icon initialization
        self.play_icon = PhotoImage(file='assets/play.png')
        self.pause_icon = PhotoImage(file='assets/pause.png')
        self.volume_min_icon = PhotoImage(file='assets/volume-min.png')
        self.volume_medium_icon = PhotoImage(file='assets/volume-medium.png')
        self.volume_max_icon = PhotoImage(file='assets/volume-max.png')
        self.volume_mute_icon = PhotoImage(file='assets/volume-mute.png')
        self.repeat_icon = PhotoImage(file='assets/repeat.png')
        self.shuffle_icon = PhotoImage(file='assets/shuffle.png')
        self.skip_back_icon = PhotoImage(file='assets/skip-back.png')
        self.skip_forward_icon = PhotoImage(file='assets/skip-forward.png')
        self.play_icon_active = PhotoImage(file='assets/play_active.png')
        self.pause_icon_active = PhotoImage(file='assets/pause_active.png')
        self.volume_min_icon_active = PhotoImage(
            file='assets/volume-min_active.png')
        self.volume_medium_icon_active = PhotoImage(
            file='assets/volume-medium_active.png')
        self.volume_max_icon_active = PhotoImage(
            file='assets/volume-max_active.png')
        self.volume_mute_icon_active = PhotoImage(
            file='assets/volume-mute_active.png')
        self.repeat_icon_active = PhotoImage(file='assets/repeat_active.png')
        self.shuffle_icon_active = PhotoImage(file='assets/shuffle_active.png')
        self.skip_back_icon_active = PhotoImage(
            file='assets/skip-back_active.png')
        self.skip_forward_icon_active = PhotoImage(
            file='assets/skip-forward_active.png')
        self.browse_file_icon = PhotoImage(file='assets/browse-file.png')
        self.browse_file_icon_active = PhotoImage(
            file='assets/browse-file_active.png')
        self.explorer_icon = PhotoImage(file='assets/explorer.png')
        self.explorer_icon_active = PhotoImage(
            file='assets/explorer_active.png')
        self.music_icon = PhotoImage(file='assets/music.png')
        self.music_icon_active = PhotoImage(file='assets/music_active.png')
        self.mute_icon = PhotoImage(file='assets/mute.png')
        self.mute_icon_active = PhotoImage(file='assets/mute_active.png')
        self.disc_icon = PhotoImage(file='assets/disc.png')
        self.disc_icon_active = PhotoImage(file='assets/disc_active.png')
        #variable initialization
        self.songstatus = StringVar()
        self.v = DoubleVar()
        self.currentsong = None
        self.pauseonly = False
        self.songlength = 1

        #post initialization
        self._widget()
        self._config()
        self._layout()

    def _widget(self):
        #widget setup
        self.play_pause_button = Button(self,
                                        image=self.play_icon,
                                        command=self.play_pause,
                                        takefocus=False,
                                        relief=FLAT,
                                        bg='grey22',
                                        activebackground='grey22')
        self.VolumeSlider = ttk.Scale(self,
                                      variable=self.v,
                                      from_=0,
                                      to=100,
                                      orient=HORIZONTAL,
                                      command=self.setvolume)
        self.music_player_scale = ttk.Scale(self,
                                            orient=HORIZONTAL,
                                            command=self.musicsliderset)
        self.volume_button = Button(self,
                                    image=self.volume_max_icon,
                                    relief=FLAT,
                                    bg='grey22',
                                    activebackground='grey22',
                                    command=self.togglemute)
        self.progress_label_1 = Label(self,
                                      text='00:00',
                                      bg='grey22',
                                      fg='white')
        self.progress_label_2 = Label(self,
                                      text='00:00',
                                      bg='grey22',
                                      fg='white')
        self.repeat_button = Button(self,
                                    image=self.repeat_icon,
                                    bg='grey22',
                                    relief=FLAT,
                                    activebackground='grey30',
                                    command=self.loopshuffletoggle)
        self.shuffle_button = Button(self,
                                     image=self.shuffle_icon,
                                     bg='grey22',
                                     relief=FLAT,
                                     activebackground='grey30',
                                     command=self.loopshuffletoggle)
        self.last_song_button = Button(self,
                                       image=self.skip_back_icon,
                                       bg='grey22',
                                       relief=FLAT,
                                       activebackground='grey22',
                                       command=self.previous_song)
        self.next_song_button = Button(self,
                                       image=self.skip_forward_icon,
                                       bg='grey22',
                                       relief=FLAT,
                                       activebackground='grey22',
                                       command=self.next_song)
        self.playlist = Listbox(self,
                                relief=FLAT,
                                selectmode=SINGLE,
                                bg="grey20",
                                fg="grey88",
                                font=('Arial', 13),
                                width=82,
                                height=15,
                                selectbackground="grey40",
                                activestyle='none')
        self.browse_button = Button(self,
                                    bg='grey30',
                                    fg='grey92',
                                    activebackground='grey70',
                                    image=self.browse_file_icon,
                                    command=self.selectpath,
                                    relief=FLAT)
        self.pathname = Label(self,
                              bg='grey22',
                              fg='white',
                              font=('arial', 10))
        self.pathtoggle = Button(self,
                                 image=self.explorer_icon,
                                 bg='grey22',
                                 relief=FLAT,
                                 width=500,
                                 height=50,
                                 command=self.toggleplaylist)
        self.nowmusictoggle = Button(self,
                                     image=self.music_icon,
                                     bg='grey30',
                                     relief=FLAT,
                                     width=500,
                                     height=50,
                                     command=self.toggleplaylist)
        self.currentvolume = Label(self,
                                   bg='grey22',
                                   fg='grey88',
                                   relief=FLAT,
                                   text='100')
        self.songname = Label(self,
                              bg='grey22',
                              fg='grey88',
                              relief=FLAT,
                              text='',
                              font=('Arial', 30, 'bold'))
        self.artistname = Label(self,
                                bg='grey22',
                                fg='grey88',
                                relief=FLAT,
                                text='',
                                font=('Arial', 13))
        self.albumname = Label(self,
                               bg='grey22',
                               fg='grey88',
                               relief=FLAT,
                               text='',
                               font=('Arial', 13))
        self.discicon = Button(image=self.disc_icon,
                               bg='grey30',
                               relief=FLAT,
                               command=self.songdetail)
        #widget binding
        self.playlist.bind('<Button-1>', self.playlistclick)
        self.playlist.bind('<Double-Button-1>', self.playlistdoubleclick)
        #24/7 threading
        self.automusicslider.daemon = True
        self.musicloop.daemon = True
        self.automusicslider.start()
        self.musicloop.start()

    def _layout(self):
        #widget placement
        self.songname.place(relx=0.25, rely=0.47)
        self.artistname.place(relx=0.25, rely=0.59)
        self.albumname.place(relx=0.25, rely=0.67)
        self.play_pause_button.place(relx=0.5, rely=0.85, anchor=CENTER)
        self.repeat_button.place(relx=0.4, rely=0.85, anchor=CENTER)
        #self.shuffle_button.place(relx=0.6, rely=0.85, anchor=CENTER)
        self.music_player_scale.place(relx=0.5,
                                      rely=0.95,
                                      width=500,
                                      anchor=CENTER)
        self.progress_label_1.place(relx=0.20, rely=0.93)
        self.progress_label_2.place(relx=0.75, rely=0.93)
        self.last_song_button.place(relx=0.45, rely=0.85, anchor=CENTER)
        self.next_song_button.place(relx=0.55, rely=0.85, anchor=CENTER)
        self.volume_button.place(relx=0.81, rely=0.845)
        self.VolumeSlider.place(relx=0.85, rely=0.85)
        self.pathtoggle.place(relx=0.0, rely=0.0)
        self.nowmusictoggle.place(relx=0.5, rely=0.0)
        self.currentvolume.place(relx=0.95, rely=0.85)
        self.discicon.place(relx=0.04, rely=0.44)

    def playlistclick(self, event):
        self.loadsong()

    def playlistdoubleclick(self, event):
        self.loadsong()
        self.toggleplaylist()
        self.play_music()

    def check_event(self):
        pass

    def _config(self):
        #variable setup
        self.VolumeSlider.set(100)
        self.songstatus.set("choosing")

        #key binding
        self.bind('<Button-1>', self._flat_button)
        self.bind('<Enter>', self._button_hover)
        self.bind('<Leave>', self._button_leave)
        self.bind('<space>', self.play_pause)

    def toggleplaylist(self):
        #toggle playlist and its accessories here
        if self.playlist.winfo_ismapped() == True:
            self.playlist.place_forget()
            self.pathname.place_forget()
            self.browse_button.place_forget()
            self.pathtoggle.config(bg='grey22')
            self.nowmusictoggle.config(bg='grey30')
        else:
            self.playlist.place(relx=0.01, rely=0.15)
            self.playlist.tkraise()
            self.pathname.place(relx=0.01, rely=0.10)
            self.browse_button.place(relx=0.96, rely=0.086)
            self.pathtoggle.config(bg='grey30')
            self.nowmusictoggle.config(bg='grey22')

    def setmusiclength(self):
        #important function on a player (also hard to do)
        if self.currentsong.endswith('.mp3') == True:
            self.song = MP3(self.currentsong)
            self.songinfo = ID3(self.currentsong)
            self.songlength = self.song.info.length
            self.songround = round(self.songlength)
            self.songmins, self.songsecs = divmod(self.songround, 60)
            self.songmins = str(self.songmins).zfill(2)
            self.songsecs = str(self.songsecs).zfill(2)
            self.progress_label_2.config(text=str(self.songmins) + ':' +
                                         str(self.songsecs))

            try:
                self.songname.config(text=self.songinfo['TIT2'].text[0])
                self.artistname.config(text=self.songinfo['TPE1'].text[0])
                self.albumname.config(text=self.songinfo['TALB'].text[0])
            except:
                self.songname.config(text=self.currentsong)
                self.artistname.config(text='failed to read metadata')
                self.albumname.config(text='failed to read metadata')

        if self.currentsong.endswith('.flac') == True:
            self.song = FLAC(self.currentsong)
            self.songlength = self.song.info.length
            self.songround = round(self.songlength)
            self.songmins, self.songsecs = divmod(self.songround, 60)
            self.songmins = str(self.songmins).zfill(2)
            self.songsecs = str(self.songsecs).zfill(2)
            self.progress_label_2.config(text=str(self.songmins) + ':' +
                                         str(self.songsecs))
            self.music_player_scale.config(from_=0, to=self.songlength)

            try:
                self.songname.config(text=self.song['TITLE'])
                self.artistname.config(text=self.song['ARTIST'])
                self.albumname.config(text=self.song['ALBUM'])
            except:
                self.songname.config(text=self.currentsong)
                self.artistname.config(text='failed to read metadata')
                self.albumname.config(text='failed to read metadata')

        if self.currentsong.endswith('.ogg') == True:
            self.song = WAVE(self.currentsong)
            self.songlength = self.song.info.length
            self.songround = round(self.songlength)
            self.songmins, self.songsecs = divmod(self.songround, 60)
            self.songsecs = str(self.songsecs).zfill(2)
            self.progress_label_2.config(text=str(self.songmins) + ':' +
                                         str(self.songsecs))

    def musicsliderset(self, *args):
        #Also important as user need to choose where to play
        #self.userlength = self.music_player_scale.get()
        #print(self.userlength)
        #mixer.music.set_pos(self.userlength)
        pass

    def musicsliderplace(self):
        for i in range(999999999):
            self.currenttime = mixer.music.get_pos()
            self.currenttime, self.currenttimemil = divmod(
                self.currenttime, 1000)
            self.currentmin, self.currentsec = divmod(self.currenttime, 60)
            self.currentmin = str(self.currentmin).zfill(2)
            self.currentsec = str(self.currentsec).zfill(2)
            self.progress_label_1.config(text=str(self.currentmin) + ':' +
                                         str(self.currentsec))
            if self.progress_label_1['text'] == '-1:59':
                self.progress_label_1.config(text='00:00')
            self.currentsongpos = int(self.currenttime) / int(self.songlength)
            self.music_player_scale.set(self.currentsongpos)

            time.sleep(1)

    def _button_hover(self, event):
        try:
            if type(event.widget) == Button:
                exec('event.widget.config(image=self.' + re.search(
                    r'assets/(.*?)\.png',
                    root.call(event.widget.cget('image'), 'cget',
                              '-file')).group(1).replace('-', '_') +
                     '_icon_active)')
        except AttributeError:
            pass

    #button hover out animation
    def _button_leave(self, event):
        if type(event.widget) == Button:
            exec('event.widget.config(image=self.' + re.search(
                r'assets/(.*?)\.png',
                root.call(event.widget.cget('image'), 'cget', '-file')).group(
                    1).replace('-', '_').replace('_active', '') + '_icon)')

    #relief locking
    def _flat_button(self, event):
        if type(event.widget) == Button:
            event.widget.config(relief=FLAT)

    #music play and pause area
    def loadsong(self):
        self.currentsong = self.playlist.get(ACTIVE)
        #loading bay

        try:
            mixer.music.load(self.currentsong)
            self.play_pause_button.config(image=self.pause_icon_active)
            self.setmusiclength()
        except pygame.error:
            mixer.music.unload()
            messagebox.showerror(title="ERROR",
                                 message="Invalid Music Format!")

    def play_music(self, *args):
        mixer.music.play()
        self.title(self.versionname + ' - Playing ' + self.currentsong)
        self.check_event()

    def loopshuffletoggle(self):
        if self.repeat_button.cget('bg') == 'grey50':
            self.repeat_button.config(bg='grey22')
        else:
            self.repeat_button.config(bg='grey50')

    def loopsong(self):
        for i in range(99999999):
            if pygame.mixer.music.get_busy(
            ) == False and self.repeat_button.cget('bg') == 'grey50':
                pygame.mixer.music.play()
            else:
                pass
            time.sleep(1)

    def play_pause(self):
        if self.play_pause_button['image'] == str(self.pause_icon_active):
            mixer.music.pause()
            self.title(self.versionname + ' - Paused ')
            self.play_pause_button.config(image=self.play_icon_active)
        else:
            mixer.music.unpause()
            self.title(self.versionname + ' - Playing ' + self.currentsong)
            self.play_pause_button.config(image=self.pause_icon_active)

    def next_song(self):
        selection_indices = self.playlist.curselection()

        # default next selection is the beginning
        next_selection = 0

        # make sure at least one item is selected
        if len(selection_indices) > 0:
            # Get the last selection, remember they are strings for some reason
            # so convert to int
            last_selection = int(selection_indices[-1])

            # clear current selections
            self.playlist.selection_clear(selection_indices)

            # Make sure we're not at the last item
            if last_selection < self.playlist.size() - 1:
                next_selection = last_selection + 1

        self.playlist.activate(next_selection)
        self.playlist.selection_set(next_selection)
        self.play_pause_button.config(image=self.pause_icon_active)
        self.loadsong()
        self.play_music()

    def previous_song(self):
        selection_indicesb = self.playlist.curselection()

        # default next selection is the beginning
        next_selectionb = 0

        # make sure at least one item is selected
        if len(selection_indicesb) > 0:
            # Get the last selection, remember they are strings for some reason
            # so convert to int
            last_selectionb = int(selection_indicesb[-1])

            # clear current selections
            self.playlist.selection_clear(selection_indicesb)

            # Make sure we're not at the last item
            if last_selectionb < self.playlist.size() - 1:
                next_selectionb = last_selectionb - 1

        self.playlist.activate(next_selectionb)
        self.playlist.selection_set(next_selectionb)
        self.play_pause_button.config(image=self.pause_icon_active)
        self.loadsong()
        self.play_music()

    #volume control
    def setvolume(self, event):
        self.volume = self.VolumeSlider.get()
        self.volumed = self.volume / 100 + 0.00
        mixer.music.set_volume(self.volumed)  #also write your code here
        self.currentvolume.config(text=int(self.volume))
        if self.volume <= 100:
            self.volume_button.config(image=self.volume_max_icon)

        if self.volume <= 70:
            self.volume_button.config(image=self.volume_medium_icon)

        if self.volume <= 40:
            self.volume_button.config(image=self.volume_min_icon)

        if self.volume == 0:
            self.volume_button.config(image=self.mute_icon)

    def togglemute(self):
        if self.VolumeSlider.get() != 0:
            #mute
            self.VolumeSlider.set(0)
        else:
            #unmute
            self.VolumeSlider.set(100)

    def songdetail(self):
        detailwindow = Toplevel()
        detailwindow.geometry('800x500')
        detailwindow.config(bg='grey22')
        detailwindow.attributes('-alpha', 0.9)
        detailwindow.title('Metadata')

        try:
            self.detailbox = Label(detailwindow,
                                   bg='grey22',
                                   fg='white',
                                   text=self.song.pprint())
            self.detailbox.pack(side=TOP)
        except:
            messagebox.showerror(title='Error',
                                 message='Failed to read metadata')

    def selectpath(self):
        path = filedialog.askdirectory()
        self.playlist.delete(0, 'end')
        try:
            os.chdir(path)
            songs = os.listdir()
            filteredsongs = filter(lambda x: x.endswith(('.mp3', '.flac')),
                                   songs)
            self.pathname.config(text='Selected path: ' + path)
            for s in filteredsongs:
                self.playlist.insert(END, s)
        except OSError:
            self.pathname.config(text='Please choose a path...')

    def ask_quit(self):
        if mixer.music.get_busy() == False:
            root.destroy()

        elif askokcancel("Exit", "Stop Music?"):
            mixer.music.stop()
            root.destroy()
def initiateWAVE(filename, directory, thumbnails, options):
    audio = WAVE(str(directory) + "/" + str(filename))
    # verify artist information is present before preceeding
    if ' - ' not in filename and str(audio['TCON']) == '':
        messagebox.showinfo("No artist information found, aborting procedure")
        return False, False, False
    # transcribe formal tagnames into informal counterpart
    formalTagDict = {
        'TPE1': 'Artist',
        'TALB': 'Album',
        'TPE2': 'Album Artist',
        'TBPM': 'BPM',
        'COMM::eng': 'Comment',
        'TCMP': 'Compilation',
        'TCOP': 'Copyright',
        'TPOS': 'Discnumber',
        'TCON': 'Genre',
        'APIC:': 'Image',
        'TKEY': 'Key',
        'TDRC': 'Release_Date',
        'TIT2': 'Title',
        'TXXX:replaygain_track_gain': 'ReplayGain',
    }
    # transcribe informal tagnames into formal counterpart
    informalTagDict = {v: k for k, v in formalTagDict.items()}

    ID3Frames = {
        'TPE1': TPE1,
        'TALB': TALB,
        'TPE2': TPE2,
        'TBPM': TBPM,
        'COMM': COMM,
        'TCMP': TCMP,
        'TCOP': TCOP,
        'TPOS': TPOS,
        'TCON': TCON,
        'APIC:': APIC,
        'TKEY': TKEY,
        'TDRC': TDRC,
        'TIT2': TIT2,
        'TXXX': TXXX,
    }
    fileParameters = []
    tagList = list(audio.keys())
    for tag in tagList:
        # delete extraneous tags if the tag is not in the list of selected tags and the delete unselected tags option is activated
        if (tag not in formalTagDict
                or formalTagDict[tag] not in options["Selected Tags (L)"]
            ) and options["Delete Unselected Tags (B)"].get() == True:
            audio.pop(tag)
            audio.save()
        else:
            fileParameters.append(tag)
    for tag in options["Selected Tags (L)"]:
        if tag in informalTagDict:
            tag = informalTagDict[tag]
            # add tags of interest if missing
            if tag not in fileParameters:
                try:
                    if "COMM" in tag:
                        audio[tag] = COMM(encoding=3, lang="eng", text="")
                    elif "TXXX" in tag:
                        audio[tag] = TXXX(encoding=3,
                                          desc="replaygain_track_gain",
                                          text="")
                    else:
                        audio[tag] = ID3Frames[tag](encoding=3, text="")
                    audio.save()
                except:
                    messagebox.showinfo(
                        "Permission Error",
                        "Unable to save tags, file may be open somewhere")
                    return False, False, False
    # check for discrepancies between tags and filename
    # check both artist and title tags
    if ' - ' in filename:
        artist = filename.split(' - ')[0]
        title = filename[filename.index(filename.split(' - ')[1]):filename.
                         rfind('.')]
        if artist != str(audio["TPE1"]) or title != str(audio["TIT2"]):
            # save artist and title to tag if both are empty
            if str(audio["TPE1"]) == '' and str(audio["TIT2"]) == '':
                audio["TPE1"] = TPE1(encoding=3, text=artist)
                audio["TIT2"] = TIT2(encoding=3, text=title)
                audio.save()
            else:
                audio, filename = compareArtistAndTitle(
                    audio, artist, title, filename, directory, options)
    # only check title tag
    else:
        title = filename[:filename.rfind('.')]
        if title != str(audio["TIT2"]):
            # save title to tag if tag is empty
            if str(audio["TIT2"]) == '':
                audio["TIT2"] = TIT2(encoding=3, text=title)
                audio.save()
            else:
                audio, filename = compareTitle(audio, title, filename,
                                               directory, options)

    # handle naming format and typo check
    if options["Audio naming format (S)"].get() == "Artist - Title" or options[
            'Audio naming format (S)'].get() == 'Title':
        namingConvention = options['Audio naming format (S)'].get()
        artist = str(audio["TPE1"])
        audio, filename = handleStaticNamingConvention(audio, filename, artist,
                                                       title, directory,
                                                       namingConvention)
        if options["Scan Filename and Tags (B)"].get(
        ) == True and type(audio) != bool:
            audio, filename, options = extractArtistAndTitle(
                audio, filename, directory, options, namingConvention)

    if type(audio) != bool:
        # save thumbnail to list
        image = audio["APIC:"]
        if image.data != b'':
            stream = BytesIO(image.data)
            image = Image.open(stream).convert("RGBA")
            thumbnails = saveThumbnail(image, thumbnails)
            stream.close()
        else:
            thumbnails = saveThumbnail("NA", thumbnails)
    return audio, filename, informalTagDict, thumbnails, options
示例#19
0
 def _get_length(self, wav_file):
     return int(WAVE(wav_file).info.length)
示例#20
0
class TWave(TestCase):
    def setUp(self):
        fn_wav_pcm_2s_16000_08_id3v23 = \
            os.path.join(DATA_DIR, "silence-2s-PCM-16000-08-ID3v23.wav")
        self.wav_pcm_2s_16000_08_ID3v23 = \
            WAVE(fn_wav_pcm_2s_16000_08_id3v23)

        self.tmp_fn_pcm_2s_16000_08_ID3v23 = \
            get_temp_copy(fn_wav_pcm_2s_16000_08_id3v23)
        self.tmp_wav_pcm_2s_16000_08_ID3v23 = \
            WAVE(self.tmp_fn_pcm_2s_16000_08_ID3v23)

        self.fn_wav_pcm_2s_16000_08_notags = \
            os.path.join(DATA_DIR, "silence-2s-PCM-16000-08-notags.wav")
        self.wav_pcm_2s_16000_08_notags = \
            WAVE(self.fn_wav_pcm_2s_16000_08_notags)

        self.tmp_fn_pcm_2s_16000_08_notag = \
            get_temp_copy(self.fn_wav_pcm_2s_16000_08_notags)
        self.tmp_wav_pcm_2s_16000_08_notag = \
            WAVE(self.tmp_fn_pcm_2s_16000_08_notag)

        fn_wav_pcm_2s_44100_16_id3v23 = \
            os.path.join(DATA_DIR, "silence-2s-PCM-44100-16-ID3v23.wav")
        self.wav_pcm_2s_44100_16_ID3v23 = WAVE(fn_wav_pcm_2s_44100_16_id3v23)

    def test_channels(self):
        self.failUnlessEqual(self.wav_pcm_2s_16000_08_ID3v23.info.channels, 2)
        self.failUnlessEqual(self.wav_pcm_2s_44100_16_ID3v23.info.channels, 2)

    def test_sample_rate(self):
        self.failUnlessEqual(self.wav_pcm_2s_16000_08_ID3v23.info.sample_rate,
                             16000)
        self.failUnlessEqual(self.wav_pcm_2s_44100_16_ID3v23.info.sample_rate,
                             44100)

    def test_number_of_samples(self):
        self.failUnlessEqual(
            self.wav_pcm_2s_16000_08_ID3v23.info._number_of_samples, 32000)
        self.failUnlessEqual(
            self.wav_pcm_2s_44100_16_ID3v23.info._number_of_samples, 88200)

    def test_bits_per_sample(self):
        self.failUnlessEqual(
            self.wav_pcm_2s_16000_08_ID3v23.info.bits_per_sample, 8)
        self.failUnlessEqual(
            self.wav_pcm_2s_44100_16_ID3v23.info.bits_per_sample, 16)

    def test_bitrate(self):
        self.failUnlessEqual(self.wav_pcm_2s_16000_08_ID3v23.info.bitrate,
                             64000)
        self.failUnlessEqual(self.wav_pcm_2s_44100_16_ID3v23.info.bitrate,
                             352800)

    def test_length(self):
        self.failUnlessAlmostEqual(self.wav_pcm_2s_16000_08_ID3v23.info.length,
                                   2.0, 2)
        self.failUnlessAlmostEqual(self.wav_pcm_2s_44100_16_ID3v23.info.length,
                                   2.0, 2)

    def test_not_my_file(self):
        self.failUnlessRaises(InvalidChunk, WAVE,
                              os.path.join(DATA_DIR, "empty.ogg"))

    def test_pprint(self):
        self.wav_pcm_2s_44100_16_ID3v23.pprint()

    def test_mime(self):
        self.failUnless("audio/wav" in self.wav_pcm_2s_44100_16_ID3v23.mime)
        self.failUnless("audio/wave" in self.wav_pcm_2s_44100_16_ID3v23.mime)

    def test_id3_tags(self):
        id3 = self.wav_pcm_2s_44100_16_ID3v23.tags
        self.assertEquals(id3["TALB"], "Quod Libet Test Data")
        self.assertEquals(id3["TCON"], "Silence")
        self.assertEquals(id3["TIT2"], "Silence")
        self.assertEquals(id3["TPE1"], ["piman / jzig"])

    def test_id3_tags_uppercase_chunk(self):
        id3 = self.wav_pcm_2s_16000_08_ID3v23
        self.assertEquals(id3["TALB"], "Quod Libet Test Data")
        self.assertEquals(id3["TCON"], "Silence")
        self.assertEquals(id3["TIT2"], "Silence")
        self.assertEquals(id3["TPE1"], ["piman / jzig"])

    def test_delete(self):
        self.tmp_wav_pcm_2s_16000_08_ID3v23.delete()

        self.failIf(self.tmp_wav_pcm_2s_16000_08_ID3v23.tags)
        self.failUnless(WAVE(self.tmp_fn_pcm_2s_16000_08_ID3v23).tags is None)

    def test_save_no_tags(self):
        self.tmp_wav_pcm_2s_16000_08_ID3v23.tags = None
        self.tmp_wav_pcm_2s_16000_08_ID3v23.save()
        self.assertTrue(self.tmp_wav_pcm_2s_16000_08_ID3v23.tags is None)

    def test_add_tags_already_there(self):
        self.failUnless(self.tmp_wav_pcm_2s_16000_08_ID3v23.tags)
        self.failUnlessRaises(Exception,
                              self.tmp_wav_pcm_2s_16000_08_ID3v23.add_tags)

    def test_roundtrip(self):
        self.failUnlessEqual(self.tmp_wav_pcm_2s_16000_08_ID3v23["TIT2"],
                             ["Silence"])
        self.tmp_wav_pcm_2s_16000_08_ID3v23.save()
        new = WAVE(self.tmp_wav_pcm_2s_16000_08_ID3v23.filename)
        self.failUnlessEqual(new["TIT2"], ["Silence"])

    def test_save_tags(self):
        from mutagen.id3 import TIT1
        tags = self.tmp_wav_pcm_2s_16000_08_ID3v23.tags
        tags.add(TIT1(encoding=3, text="foobar"))
        tags.save()

        new = WAVE(self.tmp_wav_pcm_2s_16000_08_ID3v23.filename)
        self.failUnlessEqual(new["TIT1"], ["foobar"])

    """" Simulate the way Picard writes and update tags """

    def test_picard_lifecycle(self):
        path_tmp_wav_file = \
            get_temp_copy(self.fn_wav_pcm_2s_16000_08_notags)
        from mutagen.id3 import ID3
        wav = WAVE(path_tmp_wav_file)
        id3 = wav.tags
        """" Picard WaveFile._get_tags: """
        self.assertIsNone(id3, "Ensure ID3-tag-header does not exist")
        """" Picard WaveFile._get_tags: initialize tags """
        wav.add_tags()
        id3 = wav.tags
        self.assertIsInstance(id3, ID3)
        """ ID3v2.3 separator """
        separator = '/'
        """ Initialize Picard like metadata tags """
        self.__init_id3_tags(id3, major=3)
        """ Write the Picard like metadata to the empty WAVE-file """
        id3.save(path_tmp_wav_file, v23_sep=separator)
        """ Tags (metadata) have been added; now load the file again """
        wav = WAVE(path_tmp_wav_file)
        id3 = wav.tags
        self.assertIsInstance(id3, ID3)
        self.assertEquals(id3["TRCK"], "1/10")
        self.assertEquals(id3["TPOS"], "1/1")
        self.assertEquals(id3["TXXX:MusicBrainz Release Group Id"],
                          "e00305af-1c72-469b-9a7c-6dc665ca9adc")
        self.assertEquals(id3["TXXX:MusicBrainz Album Artist Id"], [
            "3fe817fc-966e-4ece-b00a-76be43e7e73c",
            "984f8239-8fe1-4683-9c54-10ffb14439e9"
        ])
        self.assertEquals(id3["TXXX:CATALOGNUMBER"], ["PRAR931391"])
        self.assertEquals(id3["TSRC"], ["NLB931100460", "USMH51100098"])

    @staticmethod
    def __init_id3_tags(id3, major=3):
        """
        Attributes:
            id3 ID3 Tag object
            major ID3 major version, e.g.: 3 for ID3v2.3
        """
        from mutagen.id3 import TRCK, TPOS, TXXX, TPUB, TALB, UFID, TPE2, \
            TSO2, TMED, TIT2, TPE1, TSRC, IPLS, TORY, TDAT, TYER
        id3.add(TRCK(encoding=major, text="1/10"))
        id3.add(TPOS(encoding=major, text="1/1"))
        id3.add(
            TXXX(encoding=major,
                 desc="MusicBrainz Release Group Id",
                 text="e00305af-1c72-469b-9a7c-6dc665ca9adc"))
        id3.add(TXXX(encoding=major, desc="originalyear", text="2011"))
        id3.add(
            TXXX(encoding=major, desc="MusicBrainz Album Type", text="album"))
        id3.add(
            TXXX(encoding=major,
                 desc="MusicBrainz Album Id",
                 text="e7050302-74e6-42e4-aba0-09efd5d431d8"))
        id3.add(TPUB(encoding=major, text="J&R Adventures"))
        id3.add(TXXX(encoding=major, desc="CATALOGNUMBER", text="PRAR931391"))
        id3.add(TALB(encoding=major, text="Don\'t Explain"))
        id3.add(
            TXXX(encoding=major,
                 desc="MusicBrainz Album Status",
                 text="official"))
        id3.add(TXXX(encoding=major, desc="SCRIPT", text="Latn"))
        id3.add(
            TXXX(encoding=major,
                 desc="MusicBrainz Album Release Country",
                 text="US"))
        id3.add(TXXX(encoding=major, desc="BARCODE", text="804879313915"))
        id3.add(
            TXXX(encoding=major,
                 desc="MusicBrainz Album Artist Id",
                 text=[
                     "3fe817fc-966e-4ece-b00a-76be43e7e73c",
                     "984f8239-8fe1-4683-9c54-10ffb14439e9"
                 ]))
        id3.add(TPE2(encoding=major, text="Beth Hart & Joe Bonamassa"))
        id3.add(TSO2(encoding=major, text="Hart, Beth & Bonamassa, Joe"))
        id3.add(TXXX(encoding=major, desc="ASIN", text="B005NPEUB2"))
        id3.add(TMED(encoding=major, text="CD"))
        id3.add(
            UFID(encoding=major,
                 owner="http://musicbrainz.org",
                 data=b"f151cb94-c909-46a8-ad99-fb77391abfb8"))
        id3.add(TIT2(encoding=major, text="Sinner's Prayer"))
        id3.add(
            TXXX(encoding=major,
                 desc="MusicBrainz Artist Id",
                 text=[
                     "3fe817fc-966e-4ece-b00a-76be43e7e73c",
                     "984f8239-8fe1-4683-9c54-10ffb14439e9"
                 ]))
        id3.add(TPE1(encoding=major, text=["Beth Hart & Joe Bonamassa"]))
        id3.add(
            TXXX(encoding=major,
                 desc="Artists",
                 text=["Beth Hart", "Joe Bonamassa"]))
        id3.add(TSRC(encoding=major, text=["NLB931100460", "USMH51100098"]))
        id3.add(
            TXXX(encoding=major,
                 desc="MusicBrainz Release Track Id",
                 text="d062f484-253c-374b-85f7-89aab45551c7"))
        id3.add(
            IPLS(encoding=major,
                 people=[["engineer", "James McCullagh"],
                         ["engineer",
                          "Jared Kvitka"], ["arranger", "Jeff Bova"],
                         ["producer", "Roy Weisman"], ["piano", "Beth Hart"],
                         ["guitar", "Blondie Chaplin"],
                         ["guitar", "Joe Bonamassa"],
                         ["percussion", "Anton Fig"], ["drums", "Anton Fig"],
                         ["keyboard", "Arlan Schierbaum"],
                         ["bass guitar", "Carmine Rojas"],
                         ["orchestra", "The Bovaland Orchestra"],
                         ["vocals", "Beth Hart"], ["vocals",
                                                   "Joe Bonamassa"]])),
        id3.add(TORY(encoding=major, text="2011"))
        id3.add(TYER(encoding=major, text="2011"))
        id3.add(TDAT(encoding=major, text="2709"))
# def convert(seconds):
#     hours = seconds // 3600
#     seconds %= 3600
#     mins = seconds // 60
#     seconds %= 60
#     return(hours, mins, seconds)

totalLength = 0
i = 1
newDirectory = mainDirectory + str(i) + "/"

os.mkdir(newDirectory)

for entry in obj:
    if entry.is_file():
        audio = WAVE(entry)
        length = int(audio.info.length)
        print("this file is " + str(length) + " seconds")
        totalLength = totalLength + length
        print("running total is " + str(totalLength) + " seconds")
        if totalLength <= 3600 and length < 600:
            shutil.move(mainDirectory + str(entry.name),
                        str(newDirectory + entry.name))
            print(entry.name + " has been moved: " + str(totalLength) +
                  " seconds have been used")
        else:
            i = i + 1
            newDirectory = mainDirectory + str(i) + "/"
            os.mkdir(newDirectory)
            shutil.move(mainDirectory + str(entry.name),
                        str(newDirectory + entry.name))
def rename(directory, filename, artist, title, extension, namingConvention):
    if namingConvention == "Artist - Title" or (namingConvention == 'Dynamic'
                                                and ' - ' in filename):
        try:
            os.rename(
                directory + '/' + filename,
                directory + '/' + str(artist) + ' - ' + str(title) + extension)
            filename = str(artist) + ' - ' + str(title) + extension
        except PermissionError:
            messagebox.showinfo(
                "Permission Error",
                "File cannot be renamed, it may still be open")
            return False, False
    elif namingConvention == "Title" or (namingConvention == 'Dynamic'
                                         and ' - ' not in filename):
        try:
            os.rename(directory + '/' + filename,
                      str(directory) + '/' + str(title) + extension)
            filename = str(title) + extension
        except PermissionError:
            messagebox.showinfo(
                "Permission Error",
                "File cannot be renamed, it may still be open")
            return False, False
    if extension == ".wav":
        audio = WAVE(str(directory) + '/' + filename)
        audio["TPE1"] = TPE1(encoding=3, text=artist)
        audio["TIT2"] = TIT2(encoding=3, text=title)
        audio.save()
        return audio, filename
    elif extension == ".flac":
        audio = FLAC(str(directory) + '/' + filename)
        audio['artist'] = artist
        audio['title'] = title
        audio.save()
        return audio, filename
    elif extension == ".aiff":
        audio = AIFF(str(directory) + '/' + filename)
        audio["TPE1"] = TPE1(encoding=3, text=artist)
        audio["TIT2"] = TIT2(encoding=3, text=title)
        audio.save()
        return audio, filename
    elif extension == ".m4a":
        audio = MP4(str(directory) + '/' + filename)
        audio["\xa9ART"] = artist
        audio["\xa9nam"] = title
        audio.save()
        return audio, filename
    elif extension == ".mp3":
        audio = MP3(str(directory) + '/' + filename)
        audio["TPE1"] = TPE1(encoding=3, text=artist)
        audio["TIT2"] = TIT2(encoding=3, text=title)
        audio.save()
        return audio, filename
    elif extension == ".ogg":
        audio = OggVorbis(str(directory) + '/' + filename)
        audio['artist'] = artist
        audio['title'] = title
        audio.save()
        return audio, filename
示例#23
0
 def test_roundtrip(self):
     self.failUnlessEqual(self.tmp_wav_pcm_2s_16000_08_ID3v23["TIT2"],
                          ["Silence"])
     self.tmp_wav_pcm_2s_16000_08_ID3v23.save()
     new = WAVE(self.tmp_wav_pcm_2s_16000_08_ID3v23.filename)
     self.failUnlessEqual(new["TIT2"], ["Silence"])
示例#24
0
def main(tex, pdf, vid, fast=False, tempo=1.0):
    lines = open(tex).readlines()
    lines = [l.strip() for l in lines]
    lines = list(filter(lambda l: '%>' in l, lines))
    cur = -1
    slideid = -1
    frames = {}
    slide_per_frame = {}
    for l in lines:
        if l == '%>next':
            cur += 1
            slideid += 1
            frames[cur] = []
            slide_per_frame[cur] = slideid
        elif l == '%>prev':
            cur += 1
            slideid -= 1
            frames[cur] = []
            slide_per_frame[cur] = slideid
        elif l == '%>stop':
            break
        else:
            frames[cur].append(l)

    tmpdir = 'slides'
    os.makedirs(tmpdir, exist_ok=True)
    density = 304.8 if not fast else 61
    command = f'convert -verbose -density {density} {pdf} {tmpdir}/%d.png'
    print(f'Executing command: {command}')
    os.system(command)

    # NOTE: the audio files are cached if the next did not change of a slide
    # delete the folder to clear the cache
    os.makedirs('audios', exist_ok=True)

    lengths = {}
    for i in sorted(frames.keys()):
        text = '\n'.join(frames[i])
        oldtext = ''
        try:
            oldtext = open(f'audios/{i}.wav.txt', 'r').read()
        except:
            pass
        if text != oldtext:
            # NOTE: the noise is just to make it a bit more real
            run(text, f'audios/{i}.wav', noise=0.0005)
            os.system(
                f'sox audios/{i}.wav audios/{i}_tuned.wav reverb 25 25 lowpass -1 2300 pitch 0 tempo {tempo}'
            )
            with open(f'audios/{i}.wav.txt', 'w') as f:
                f.write(text)
        length = WAVE(f'audios/{i}_tuned.wav').info.length
        lengths[i] = length
        print(i, length)
    files = ' '.join(f'audios/{i}_tuned.wav' for i in sorted(frames.keys()))
    os.system(f'sox --combine concatenate {files} audio.mp3 rate -v 44100')

    images = {}
    for f in sorted(frames.keys()):
        p = f'slides/{slide_per_frame[f]}.png'
        i = iio.read(p)
        print(f'{p}: {i.shape}')
        if i.shape[2] == 3:
            pass
        elif i.shape[2] == 4:
            # i.e. with an alpha channel (in [0., 255.])
            # 255 seems to mean opaque, so I guess 0 is fully transparent
            i = i[:,:,0:3] * (i[:,:,3:] / 255.) \
                + np.full(i.shape, 255.)[:,:,0:3] * (1. - i[:,:,3:] / 255.)
            print(f'{p}: {i.shape} (same image, removed alpha channel)')
        elif i.shape[2] == 1:  # iio gives (h, w, 1) shape for gray images
            i = np.repeat(i, 3, axis=2)
            print(f'{p}: {i.shape} (same image, replicated single channel)')
        else:
            print(f'ERROR: Incorrect number of channels in image {p}')
            raise ValueError

        i = i.astype(np.uint8)
        images[f] = i.astype(np.uint8)

    height, width, _ = i.shape
    audio_stream = ffmpeg.input('audio.mp3')
    process = (ffmpeg.input(
        'pipe:',
        format='rawvideo',
        pix_fmt='rgb24',
        s='{}x{}'.format(width, height),
        r=framerate).concat(audio_stream.audio, a=1).output(
            vid,
            pix_fmt=pix_fmt,
            crf=crf,
            preset=preset,
            vcodec=vcodec,
            r=framerate,
            tune='stillimage').overwrite_output().run_async(pipe_stdin=True))

    acclengths = 0
    accframe = 0
    for f in sorted(frames.keys()):
        frame = images[f]
        l = lengths[f]
        while accframe < (acclengths + l) * framerate:
            process.stdin.write(frame.astype(np.uint8).tobytes())
            accframe += 1
        acclengths += l

    process.stdin.close()
    process.wait()
    print(acclengths / 60, 'minutes')
示例#25
0
def speech_to_text(filename, cursor):

    # Из полученной строки вынимаем нужные нам параметры
    # We extract the parameters we need from the received string
    path = filename.split(
        '.wav'
    )[0] + '.wav'  # нужно чтобы учесть папки у которых в названии есть пробел
    filename = filename.replace(path + ' ', '')
    parameters = [path]
    parameters.extend(filename.split(' '))

    # проверяем что нету не заданных параметров
    # check that there are no parameters that are not set
    if len(parameters) != 4:
        log(
            f'date:{datetime.datetime.today().strftime("%Y-%m-%d")} time:{datetime.datetime.today().strftime("%H:%M")}'
            f' id:{1} AO:{""} phone:{""} audio_length:{""} result:{""} '
            f'except:{"Неверное колличество параметров! Вы должны указать 4 параметра через пробел"}',
            False)
        raise Exception(
            'Неверное колличество параметров! Вы должны указать 4 параметра через пробел\n'
            'Example: Путь телефон флаг_записи_БД этап')

    # получаем переменные
    # getting variables
    path, phone, flag_bd, step = parameters[0], parameters[1], parameters[
        2], parameters[3]

    try:
        response = client.recognize(path, audio_config)
        print(response)

        # первый случай
        # first case
        if step == '1':

            # задаем множество со словами, которые нужно отследить
            # specify multiple words that you want to monitor
            checklist = {'автоответчик', 'сигнала'}
            common_words = set(response[0]["alternatives"][0]
                               ["transcript"].split()) & checklist
            if len(common_words) > 0:
                AO = 'AO'
            else:
                AO = 'человек'

        # второй случай
        # second case
        elif step == '2':

            # задаем множество со словами, которые нужно отследить
            # specify multiple words that you want to monitor
            checklist = {'да', 'удобно', 'говорите', 'слушаю'}
            common_words = set(response[0]["alternatives"][0]
                               ["transcript"].split()) & checklist

            if len(common_words) > 0:
                AO = 'положительно'
            else:
                AO = 'отрицательно'

        else:
            log(
                f'date:{datetime.datetime.today().strftime("%Y-%m-%d")} time:{datetime.datetime.today().strftime("%H:%M")}'
                f' id:{1} AO:{""} phone:{phone} audio_length:{""} result:{""} '
                f'except:{"Этап распознования может быть либо 1 либо 2"}',
                False)
            raise Exception('Этап распознования может быть либо 1 либо 2')

        # получаем длину аудио
        # get the length of audio
        audio_length = str(WAVE('1.wav').info.length)

        # запись в бд
        # the record in the database
        if flag_bd == '1':

            # в качестве ProjectID будем брать этап распознавания, а в качестве ServerID будем брать flag_bd
            # we will use the recognition stage as the ProjectID, and we will use flag_bd as the ServerID
            cursor['cursor'].execute(
                f'INSERT INTO speech_to_text.operations (data,time,ao,phone,audio_length, result, ProjectID, ServerID)'
                f' VALUES (\'{datetime.datetime.today().strftime("%Y-%m-%d")}\','
                f' \'{datetime.datetime.today().strftime("%H:%M")}\', \'{AO}\', \'{phone}\', \'{audio_length}\','
                f' \'{response[0]["alternatives"][0]["transcript"]}\', {step}, {flag_bd}) RETURNING id'
            )

            # получаем уникальный id записи в БД
            # get the unique id of the database entry
            id = cursor['cursor'].fetchone()[0]
            cursor['conection'].commit()
        else:
            with open('log.txt') as f:
                id = str(sum(1 for _ in f)) + 'n'

        # логируем успешный вариант
        # log the successful option
        log(
            f'date:{str(datetime.datetime.today().strftime("%Y-%m-%d"))} time:\'{str(datetime.datetime.today().strftime("%H:%M"))}\''
            f' id:{id} AO:{AO} phone:{phone} audio_length:{audio_length} result:{response[0]["alternatives"][0]["transcript"]}',
            True)

        # Возвращаем в зависимости от шага и распознания
        # We return it depending on the step and recognition
        if (AO == 'AO') or (AO == 'отрицательно'):
            return 0
        else:
            return 1

    except Exception as e:
        log(
            f'date:{datetime.datetime.today().strftime("%Y-%m-%d")} time:{datetime.datetime.today().strftime("%H:%M")}'
            f' id:{1} AO:{""} phone:{phone} audio_length:{""} result:{""} except:{str(e)}',
            False)
示例#26
0
def get_seconds_duration(track):
    audio = WAVE(f'./AUDIO/{selected_playlist.replace(".txt", "")}/{track}')
    audio_info = audio.info
    length = int(audio_info.length)
    return length
示例#27
0
    def test_delete(self):
        self.tmp_wav_pcm_2s_16000_08_ID3v23.delete()

        self.failIf(self.tmp_wav_pcm_2s_16000_08_ID3v23.tags)
        self.failUnless(WAVE(self.tmp_fn_pcm_2s_16000_08_ID3v23).tags is None)
示例#28
0
def grab_reddit_data(submission_id, reddit, videoexport):
    target_submission = reddit.submission(id=submission_id)
    # target_submission.comment_sort = "top"

    # general data regarding the post
    main_post_dict = {
        "id": submission_id,
        "title": target_submission.title,
        "body": target_submission.selftext,
        "upvotes": target_submission.score,
        "subreddit": target_submission.subreddit_name_prefixed,
        "comments": target_submission.comments,
        "author": target_submission.author,
        "url": target_submission.url,
        "css-selector": target_submission.name
    }

    reddit_data = {"general": main_post_dict}
    comment_data = []
    if bool(videoexport['video']['comment_size_is_seconds']):
        counter = 0
        i = 0  # number of iteration in the while loop

        comments = deepcopy(target_submission.comments)
        comments = list(comments)  # get all top level comments as a list

        while counter < videoexport['video']['comment_size']:
            comment = get_reddit_comment(i, comments)
            cmnt = {
                "id": comment.id,
                "author": comment.author,
                "body": comment.body,
                "name": comment.name
            }

            comment_data.append(cmnt)
            tmplocation = "tmp/" + comment.id + ".mp3"

            balcon_tts(voicename=videoexport['tts']['voice'],
                       speed=videoexport['tts']['speed'],
                       volume=videoexport['tts']['volume'],
                       outputfile=tmplocation,
                       text=re.sub(r'\\\B', r'', cmnt['body']))

            audio = WAVE(tmplocation)
            audio_info = audio.info
            length = int(audio_info.length)

            counter += length

            i += 1

        shutil.rmtree("tmp")
        os.mkdir("tmp")
    else:
        i = 0  # number of iteration in the while loop

        comments = deepcopy(target_submission.comments)
        comments = list(comments)  # get all top level comments as a list

        while i < videoexport['video']['comment_size']:
            comment = get_reddit_comment(i, comments)
            cmnt = {
                "id": comment.id,
                "author": comment.author,
                "body": comment.body,
                "name": comment.name
            }

            comment_data.append(cmnt)

            i += 1

    reddit_data['comment_data'] = comment_data
    return reddit_data
示例#29
0
sound.export(dst, format="wav")


# function to convert the information into some readable format
def audio_duration(length):
    hours = length // 3600  # calculate in hours
    length %= 3600
    mins = length // 60  # calculate in minutes
    length %= 60
    seconds = length  # calculate in seconds

    return hours, mins, seconds  # returns the duration


# Create a WAVE object Specify the directory address of your wavpack file
audio = WAVE(dst)

# contains all the metadata about the wavpack file
audio_info = audio.info
length = audio_info.length

#getting information about file
time_series, sample_rate = librosa.load(dst)

# getting a matrix which contains amplitude values according to frequency and time indexes
stft = np.abs(librosa.stft(time_series, hop_length=512, n_fft=2048 * 4))

# converting the matrix to decibel matrix
spectrogram = librosa.amplitude_to_db(stft, ref=np.max)

# getting an array of frequencies