Esempio n. 1
0
 def run_command(args: List[str],
                 progress: Progress,
                 start: int = 0,
                 duration: Optional[int] = None) -> None:
     """
     Start a new process running specified command and wait for it to complete.
     :duration: If not None, the progress percentage will be updated based upon
     the amount of time the process has been running.
     Can be terminated by setting progress.abort to True
     """
     progress.pct = 0.0
     start_time = time.time()
     with subprocess.Popen(args) as proc:
         done = False
         while not done and not progress.abort:
             rcode = proc.poll()
             if rcode is not None:
                 done = True
                 proc.wait()
             else:
                 if duration is not None:
                     elapsed = min(duration,
                                   1000.0 * (time.time() - start_time))
                     progress.pct = 100.0 * elapsed / float(duration)
                     progress.pct_text = Duration(int(elapsed) +
                                                  start).format()
                 time.sleep(0.25)
         if progress.abort:
             proc.terminate()
             proc.wait()
     progress.pct = 100.0
Esempio n. 2
0
 def _generate(self, destination: MP3FileWriter,
               progress: Progress) -> None:
     """generate output file, combining all input files"""
     assert destination._metadata is not None
     output: Optional[AudioSegment] = None
     num_files = float(len(destination._files))
     for index, mp3file in enumerate(destination._files, 1):
         progress.pct = 50.0 * index / num_files
         progress.text = f'Adding {mp3file.filename.name}'
         if progress.abort:
             return
         seg = AudioSegment.from_mp3(str(mp3file.filename))
         if mp3file.start is not None and mp3file.start > 0:
             if mp3file.end is not None:
                 seg = seg[mp3file.start:mp3file.end]
             else:
                 seg = seg[mp3file.start:]
         elif mp3file.end is not None:
             seg = seg[:mp3file.end]
         if mp3file.headroom is not None:
             seg = seg.normalize(mp3file.headroom)
         if output is None:
             output = seg
         else:
             output = output.append(seg, crossfade=int(mp3file.overlap))
     tags: Dict[str, Any] = {
         "artist": destination._metadata.artist,
         "title": destination._metadata.title
     }
     if destination._metadata.album:
         tags["album"] = destination._metadata.album
     assert output is not None
     progress.text = f'Encoding MP3 file "{destination.filename.name}"'
     progress.pct = 50.0
     if progress.abort:
         return
     dest_dir = destination.filename.parent
     if not dest_dir.exists():
         dest_dir.mkdir(parents=True)
     parameters = [
         '-ar',
         str(destination._metadata.sample_rate),
         '-ac',
         str(destination._metadata.channels),
     ]
     #parameters.append(f'-acodec copy')
     output.export(str(destination.filename),
                   format="mp3",
                   bitrate=f'{destination._metadata.bitrate}k',
                   parameters=parameters,
                   tags=tags)
     progress.pct = 100.0
Esempio n. 3
0
 def render(self, filename: str, document: DG.Document,
            progress: Progress) -> None:
     """Renders the given document as a PDF file"""
     # pagesize is a tuple of (width, height)
     # see reportlab.lib.pagesizes for detains
     doc = self.render_document(filename, document)
     elements: List[Flowable] = []
     num_elts = float(len(document._elements))
     for index, elt in enumerate(document._elements):
         progress.pct = 100.0 * float(index) / num_elts
         elements.append(self.renderers[type(elt)](elt))
     doc.build(elements)
     progress.pct = 100.0
Esempio n. 4
0
 def _generate(self, destination: MP3FileWriter, progress: Progress) -> None:
     """
     generate output file, combining all input files
     """
     num_files = float(len(destination._files))
     contents: List[Dict] = []
     metadata: Optional[Dict] = None
     if destination._metadata is not None:
         metadata = destination._metadata.as_dict()
     for index, mp3file in enumerate(destination._files, 1):
         progress.pct = 100.0 * index / num_files
         progress.text = f'Adding {mp3file.filename.name}'
         src: Dict[str, Union[str, int]] = {
             'filename': mp3file.filename.name
         }
         if mp3file.start is not None:
             src['start'] = mp3file.start
         if mp3file.end is not None:
             src['end'] = mp3file.end
         if mp3file.headroom is not None:
             src['headroom'] = mp3file.headroom
         contents.append(src)
     results: Dict[str, Union[List, Optional[Dict]]] = {
         'contents': contents,
         'metadata': metadata,
     }
     self.output[destination.filename.name] = self.flatten(results)
Esempio n. 5
0
 def _generate(self, destination: MP3FileWriter,
               progress: Progress) -> None:
     """generate output file, combining all input files"""
     output: Optional[AudioSegment] = None
     num_files = float(len(destination._files))
     for index, mp3file in enumerate(destination._files, 1):
         progress.pct = 50.0 * index / num_files
         progress.text = f'Adding {mp3file.filename.name}'
         if progress.abort:
             return
         seg = AudioSegment.from_mp3(str(mp3file.filename))
         if mp3file.start is not None:
             if mp3file.end is not None:
                 seg = seg[mp3file.start:mp3file.end]
             else:
                 seg = seg[mp3file.start:]
         elif mp3file.end is not None:
             seg = seg[:mp3file.end]
         if mp3file.headroom is not None:
             seg = seg.normalize(mp3file.headroom)
         if output is None:
             output = seg
         else:
             output += seg
     tags = None
     if destination._metadata is not None:
         tags = {
             "artist": Song.clean(destination._metadata.artist),
             "title": Song.clean(destination._metadata.title)
         }
         if destination._metadata.album:
             tags["album"] = Song.clean(destination._metadata.album)
     assert output is not None
     progress.text = f'Encoding MP3 file "{destination.filename.name}"'
     progress.pct = 50.0
     if progress.abort:
         return
     dest_dir = destination.filename.parent
     if not dest_dir.exists():
         dest_dir.mkdir(parents=True)
     output.export(str(destination.filename),
                   format="mp3",
                   bitrate=destination.bitrate,
                   tags=tags)
     progress.pct = 100.0
Esempio n. 6
0
 def search(self, parser: MP3Parser, progress: Progress) -> None:
     """
     Walk self._fullpath searching for all songs and
     sub-directories.
     This function will block until all of the songs and
     directories have been checked.
     """
     try:
         max_workers = len(os.sched_getaffinity(0)) + 2  # type: ignore
     except AttributeError:
         cpu_count = os.cpu_count()
         if cpu_count is None:
             max_workers = 3
         else:
             max_workers = cpu_count + 2
     with futures.ThreadPoolExecutor(max_workers=max_workers) as pool:
         todo = set(self.search_async(pool, parser, 0))
         done: Set[futures.Future] = set()
         while todo and not progress.abort:
             completed, not_done = futures.wait(
                 todo, timeout=0.25, return_when=futures.FIRST_COMPLETED)
             todo.update(set(not_done))
             for future in completed:
                 if progress.abort:
                     break
                 try:
                     err = future.exception()
                     if err is not None:
                         progress.text = f'Error: {err}'
                     else:
                         result = future.result()
                         if isinstance(result, list):
                             todo.update(set(result))
                         elif result is not None:
                             progress.text = result.filename
                 except (futures.TimeoutError, futures.CancelledError):
                     pass
                 except KeyboardInterrupt:
                     progress.abort = True
                 todo.remove(future)
                 done.add(future)
             num_tasks = len(todo) + len(done)
             if num_tasks > 0:
                 progress.pct = 100.0 * len(done) / num_tasks
Esempio n. 7
0
    def play_with_pyaudio(seg: AudioSegment, progress: Progress) -> None:
        """use pyaudio library to play audio segment"""
        pya = pyaudio.PyAudio()
        stream = pya.open(format=pya.get_format_from_width(seg.sample_width),
                          channels=seg.channels,
                          rate=seg.frame_rate,
                          output=True)

        try:
            chunks = utils.make_chunks(seg, 500)
            scale: float = 1.0
            if chunks:
                scale = 100.0 / float(len(chunks))
            for index, chunk in enumerate(chunks):
                if progress.abort:
                    break
                progress.pct = index * scale
                stream.write(chunk._data)
        finally:
            stream.stop_stream()
            stream.close()
            pya.terminate()