Exemplo n.º 1
0
def _audio_time(atuple):
    audio, atag, advanced, _, _ = atuple
    if advanced:
        param = ast.literal_eval(atag)
        audio.add(TIME(3, param[1]))
    else:
        audio.add(TIME(3, atag))
Exemplo n.º 2
0
 def test_tyer_tdat_time(self):
     id3 = ID3()
     id3.version = (2, 3)
     id3.add(TYER(encoding=0, text="2006"))
     id3.add(TDAT(encoding=0, text="0603"))
     id3.add(TIME(encoding=0, text="1127"))
     id3.update_to_v24()
     self.failUnlessEqual(id3["TDRC"], "2006-03-06 11:27:00")
Exemplo n.º 3
0
 def test_multiple_tyer_tdat_time(self):
     id3 = ID3()
     id3.version = (2, 3)
     id3.add(TYER(text=['2000', '2001', '2002', '19xx', 'foo']))
     id3.add(TDAT(text=['0102', '0304', '1111bar']))
     id3.add(TIME(text=['1220', '1111quux', '1111']))
     id3.update_to_v24()
     assert [str(t) for t in id3['TDRC']] == \
         ['2000-02-01 12:20:00', '2001-04-03', '2002']
Exemplo n.º 4
0
    def update_to_v23(self, join_with="/"):
        """Convert older (and newer) tags into an ID3v2.3 tag.

This updates incompatible ID3v2 frames to ID3v2.3 ones. If you
intend to save tags as ID3v2.3, you must call this function
at some point.
"""

        if self.version < (2, 3, 0):
            del self.unknown_frames[:]

        # TMCL, TIPL -> TIPL
        if "TIPL" in self or "TMCL" in self:
            people = []
            if "TIPL" in self:
                f = self.pop("TIPL")
                people.extend(f.people)
            if "TMCL" in self:
                f = self.pop("TMCL")
                people.extend(f.people)
            if "IPLS" not in self:
                self.add(IPLS(encoding=f.encoding, people=people))

        # TODO:
        # * EQU2 -> EQUA
        # * RVA2 -> RVAD

        # TDOR -> TORY
        if "TDOR" in self:
            f = self.pop("TDOR")
            if f.text:
                d = f.text[0]
                if d.year and "TORY" not in self:
                    self.add(TORY(encoding=f.encoding, text="%04d" % d.year))

        # TDRC -> TYER, TDAT, TIME
        if "TDRC" in self:
            f = self.pop("TDRC")
            if f.text:
                d = f.text[0]
                if d.year and "TYER" not in self:
                    self.add(TYER(encoding=f.encoding, text="%04d" % d.year))
                if d.month and d.day and "TDAT" not in self:
                    self.add(
                        TDAT(encoding=f.encoding,
                             text="%02d%02d" % (d.day, d.month)))
                if d.hour and d.minute and "TIME" not in self:
                    self.add(
                        TIME(encoding=f.encoding,
                             text="%02d%02d" % (d.hour, d.minute)))

        if "TCON" in self:
            self["TCON"].genres = self["TCON"].genres

        if self.version < (2, 3):
            # ID3v2.2 PIC frames are slightly different.
            pics = self.getall("APIC")
            mimes = {"PNG": "image/png", "JPG": "image/jpeg"}
            self.delall("APIC")
            for pic in pics:
                newpic = APIC(encoding=pic.encoding,
                              mime=mimes.get(pic.mime, pic.mime),
                              type=pic.type,
                              desc=pic.desc,
                              data=pic.data)
                self.add(newpic)

            # ID3v2.2 LNK frames are just way too different to upgrade.
            self.delall("LINK")

        # leave TSOP, TSOA and TSOT even though they are officially defined
        # only in ID3v2.4, because most applications use them also in ID3v2.3

        # New frames added in v2.4.
        for key in [
                "ASPI", "EQU2", "RVA2", "SEEK", "SIGN", "TDRL", "TDTG", "TMOO",
                "TPRO"
        ]:
            if key in self:
                del (self[key])

        for frame in self.values():
            # ID3v2.3 doesn't support UTF-8 (and WMP can't read UTF-16 BE)
            if hasattr(frame, "encoding"):
                if frame.encoding > 1:
                    frame.encoding = 1
            # ID3v2.3 doesn't support multiple values
            if isinstance(frame, mutagen.id3.TextFrame):
                try:
                    frame.text = [join_with.join(frame.text)]
                except TypeError:
                    frame.text = frame.text[:1]
Exemplo n.º 5
0
 def test_time_dropped(self):
     id3 = ID3()
     id3.version = (2, 3)
     id3.add(TIME(encoding=0, text=["1155"]))
     id3.update_to_v24()
     self.assertFalse(id3.getall("TIME"))
Exemplo n.º 6
0
def download(broadcast, targetDir, reliveUrlTemplate):
    broadcastStartDT = parse(broadcast['start'])
    broadcastEndDT = parse(broadcast['end'])

    # build filename from channel, show title and broadcast datetime, while escaping "bad" characters
    filename = os.path.join(
        targetDir,
        re.sub(
            '[^\w\s\-\.\[\]]', '_',
            broadcast['trackingInfos']['pageVars']['broadcast_service'] + ' ' +
            broadcastStartDT.astimezone(
                pytz.timezone('Europe/Berlin')).strftime("%Y-%m-%d %H:%M") +
            ' ' + broadcast['trackingInfos']['pageVars']['topline']) + ".mp3")

    # skip broadcast if file is already exists
    if os.path.isfile(filename) and os.path.getsize(filename) > 0:
        print("%s already exists, skipping." % filename, flush=True)
        return

    # get links to all audio segments of this broadcast
    segmentUrls = getSegmentUrls(broadcastStartDT, broadcastEndDT,
                                 reliveUrlTemplate)
    if segmentUrls is None:
        # skip broadcast if no segments available
        print("Skipping %s, not yet in relive" % filename)
        return

    # dowload all ts segments, and convert them to mp3
    print("Downloading %s ..." % filename, end=" ", flush=True)

    try:
        sound = AudioSegment.empty()
        for i in segmentUrls:
            sound += AudioSegment.from_file(BytesIO(urlopen(i).read()))
        sound.export(filename, format="mp3")
    except:
        print("failed.", flush=True)
        return
    else:
        print("done.", flush=True)

    # ID3: remove all tags
    try:
        tags = ID3(filename)
        tags.delete()
    except ID3NoHeaderError:
        tags = ID3()

    # ID3: save as much information as possible in the ID3 tags
    tags.add(
        TRSN(
            text=[broadcast['trackingInfos']['pageVars']['broadcast_service']
                  ]))
    tags.add(
        TPE1(
            text=[broadcast['trackingInfos']['pageVars']['broadcast_service']
                  ]))
    tags.add(
        TALB(text=[
            " - ".join(
                list(
                    dict.fromkeys([
                        broadcast['trackingInfos']['pageVars']['topline'],
                        broadcast['trackingInfos']['pageVars']['title']
                    ])))
        ]))
    tags.add(TRCK(text=['1/1']))
    #tags.add(TIT2(text=[broadcastStartDT.astimezone(pytz.timezone('Europe/Berlin')).strftime("%Y-%m-%d %H:%M")]))
    tags.add(TIT2(text=[broadcast['publicationOf']['title']]))
    tags.add(
        COMM(lang="deu",
             desc="desc",
             text=[broadcast['publicationOf']['description']]))
    tags.add(
        TYER(text=[
            broadcastStartDT.astimezone(pytz.timezone(
                'Europe/Berlin')).strftime("%Y")
        ]))
    tags.add(
        TDAT(text=[
            broadcastStartDT.astimezone(pytz.timezone(
                'Europe/Berlin')).strftime("%d%m")
        ]))
    tags.add(
        TIME(text=[
            broadcastStartDT.astimezone(pytz.timezone(
                'Europe/Berlin')).strftime("%H%M")
        ]))
    tags.add(
        TLEN(text=[
            int((broadcastEndDT - broadcastStartDT).total_seconds() * 1000)
        ]))
    tags.add(WOAS(url=broadcast['publicationOf']['canonicalUrl']))
    tags.add(WORS(url="https://www.br.de/radio/"))

    # ID3: chapters
    chapterNr = 0
    for chapter in broadcast['items']:
        chapterStartDT = parse(chapter['start'])

        if 'duration' in chapter and chapter['duration'] is not None:
            chapterEndDT = chapterStartDT + timedelta(
                seconds=chapter['duration'])
        else:
            chapterEndDT = broadcastEndDT

        artists = []
        for i in ['performer', 'author']:
            if i in chapter and chapter[i] is not None and len(chapter[i]) > 0:
                artists.append(chapter[i])

        titles = []
        for i in ['title']:
            if i in chapter and chapter[i] is not None and len(chapter[i]) > 0:
                titles.append(chapter[i])

        tags.add(
            CHAP(element_id=chapterNr,
                 start_time=floor(
                     (chapterStartDT - broadcastStartDT).total_seconds() *
                     1000),
                 end_time=ceil(
                     (chapterEndDT - broadcastStartDT).total_seconds() * 1000),
                 sub_frames=[
                     TIT2(text=[
                         " - ".join([" ".join(artists), " ".join(titles)])
                     ])
                 ]))
        chapterNr += 1

    tocList = ",".join([str(i) for i in range(0, chapterNr)])

    tags.add(
        CTOC(element_id="toc",
             flags=CTOCFlags.TOP_LEVEL | CTOCFlags.ORDERED,
             child_element_ids=[tocList],
             sub_frames=[TIT2(text=["Table Of Contents"])]))

    # ID3: cover image
    response = requests.get(
        broadcast['publicationOf']['defaultTeaserImage']['url'], timeout=5)
    if response.status_code == 200:
        tags.add(
            APIC(mime=response.headers['content-type'],
                 desc="Front Cover",
                 data=response.content))

    # save ID3 tags
    tags.save(filename, v2_version=3)
Exemplo n.º 7
0
        try:
            tags = ID3(showInfo['parts'][partNo]['filepath'] + ".part")
            tags.delete()
        except ID3NoHeaderError:
            tags = ID3()

        tags.add(TRSN(text=[stationInfo['name']]))
        tags.add(TPE1(text=[stationInfo['name']]))
        tags.add(TALB(text=[showInfo['name']]))
        tags.add(
            TRCK(text=[str(partNo + 1) + "/" + str(len(showInfo['parts']))]))
        tags.add(TIT2(text=[showInfo['parts'][partNo]['title']]))
        tags.add(COMM(lang="deu", desc="desc", text=[showInfo['description']]))
        tags.add(TYER(text=[showInfo['start_dt'].strftime("%Y")]))
        tags.add(TDAT(text=[showInfo['start_dt'].strftime("%d%m")]))
        tags.add(TIME(text=[showInfo['start_dt'].strftime("%H%M")]))
        tags.add(TLEN(text=[showInfo['parts'][partNo]['duration_ms']]))
        tags.add(WOAS(url=showInfo['website']))
        tags.add(WORS(url=stationInfo['website']))

        for chapter in showInfo['parts'][partNo]['chapters']:
            tags.add(
                CHAP(element_id=chapter["id"],
                     start_time=chapter["start_ms"],
                     end_time=chapter["end_ms"],
                     sub_frames=[TIT2(text=[chapter["title"]])]))

        tocList = ",".join([
            chapter["id"] for chapter in showInfo['parts'][partNo]['chapters']
        ])
        tags.add(