Ticket #5928: iptvfeederhttp-draft.diff

File iptvfeederhttp-draft.diff, 10.0 KB (added by dekarl@…, 17 years ago)

draft support for mp3 over http radio stations (might not even compile)

  • iptv/iptvfeederhttp.cpp

     
     1/** -*- Mode: c++ -*-
     2 *  IPTVFeederHTTP
     3 *  Copyright (c) 2008 by Karl Dietz
     4 *  Copyright (c) 2006 by Mike Mironov & Mickaël Remars
     5 *  Distributed as part of MythTV under GPL v2 and later.
     6 */
     7#include <algorithm>
     8
     9#include "iptvfeederhttp.h"
     10
     11// Qt headers
     12#include <QUrl>
     13
     14// Live555 headers
     15#include <BasicUsageEnvironment.hh>
     16#include <MP3HTTPSource.hh>
     17#include <MPEG2TransportStreamFromESSource.hh>
     18
     19// MythTV headers
     20#include "iptvmediasink.h"
     21#include "libmyth/mythcontext.h"
     22#include "libmythdb/mythverbose.h"
     23#include "tspacket.h"
     24
     25#define LOC QString("IPTVFeedHTTP: ")
     26#define LOC_ERR QString("IPTVFeedHTTP, Error: ")
     27
     28IPTVFeederHTTP::IPTVFeederHTTP() :
     29    _source(NULL),
     30    _multiplexor(NULL),
     31    _sink(NULL)
     32{
     33    VERBOSE(VB_RECORD, LOC + "ctor -- success");
     34}
     35
     36IPTVFeederHTTP::~IPTVFeederHTTP()
     37{
     38    VERBOSE(VB_RECORD, LOC + "dtor -- begin");
     39    Close();
     40    VERBOSE(VB_RECORD, LOC + "dtor -- end");
     41}
     42
     43bool IPTVFeederHTTP::IsHTTP(const QString &url)
     44{
     45    return url.startsWith("http://", Qt::CaseInsensitive);
     46}
     47
     48bool IPTVFeederHTTP::Open(const QString &url)
     49{
     50    VERBOSE(VB_RECORD, LOC + QString("Open(%1) -- begin").arg(url));
     51
     52    QMutexLocker locker(&_lock);
     53
     54    if (_source)
     55    {
     56        VERBOSE(VB_RECORD, LOC + "Open() -- end 1");
     57        return true;
     58    }
     59
     60    QUrl parse(url);
     61    if (!parse.isValid() || parse.host().isEmpty() || (-1 == parse.port()))
     62    {
     63        VERBOSE(VB_RECORD, LOC + "Open() -- end 2");
     64        return false;
     65    }
     66
     67        /* FIXME resolve target */
     68    QByteArray host = parse.host().toLatin1();
     69    struct in_addr addr;
     70    addr.s_addr = our_inet_addr(host.constData());
     71    NetAddress _target_address (addr.s_addr);
     72
     73    // Begin by setting up our usage environment:
     74    if (!InitEnv())
     75        return false;
     76
     77        _source = MP3HTTPSource::createNew(*_live_env, addr, parse.port(80), parse.encodedHost().constData(), parse.encodedPath().constData());
     78    if (!_source)
     79    {
     80        VERBOSE(VB_IMPORTANT, LOC + "Failed to create Live MP3 HTTP Source.");
     81
     82        if (socket)
     83            delete socket;
     84
     85        FreeEnv();
     86        return false;
     87    }
     88
     89        _multiplexor = MPEG2TransportStreamFromESSource::createNew(__live_env);
     90    if (!_multiplexor)
     91    {
     92        VERBOSE(VB_IMPORTANT, LOC + "Failed to create MPEG 2 Transport Stream From ES Source Filter.");
     93
     94        FreeEnv();
     95        return false;
     96    }
     97    /* attach MPEG2 Audio Layer 1-3 ES to TS */
     98    _multiplexor -> addNewAudioSource (_source, 2);
     99
     100        /* TODO a buffer worth about 5 seconds at 40mbit/s, why? We just take 300kbit/s here,
     101         * as we deal mostly with radio streams of at most 256bkit/s for the audiostream
     102         */
     103    _sink = IPTVMediaSink::CreateNew(*_live_env, TSPacket::SIZE * 1*1024);
     104    if (!_sink)
     105    {
     106        VERBOSE(VB_IMPORTANT,
     107                QString("IPTV # Failed to create sink: %1")
     108                .arg(_live_env->getResultMsg()));
     109
     110        Medium::close(_multiplexor);
     111        _multiplexor = NULL;
     112        Medium::close(_source);
     113        _source = NULL;
     114        FreeEnv();
     115
     116        return false;
     117    }
     118
     119    _sink->startPlaying(*_source, NULL, NULL);
     120    vector<TSDataListener*>::iterator it = _listeners.begin();
     121    for (; it != _listeners.end(); ++it)
     122        _sink->AddListener(*it);
     123
     124    VERBOSE(VB_RECORD, LOC + "Open() -- end");
     125
     126    return true;
     127}
     128
     129void IPTVFeederHTTP::Close(void)
     130{
     131    VERBOSE(VB_RECORD, LOC + "Close() -- begin");
     132    Stop();
     133
     134    QMutexLocker locker(&_lock);
     135
     136    if (_sink)
     137    {
     138        Medium::close(_sink);
     139        _sink = NULL;
     140    }
     141
     142    if (_multiplexor)
     143    {
     144        Medium::close(_multiplexor);
     145        _multiplexor = NULL;
     146    }
     147
     148    if (_source)
     149    {
     150        Medium::close(_source);
     151        _source = NULL;
     152    }
     153
     154    FreeEnv();
     155
     156    VERBOSE(VB_RECORD, LOC + "Close() -- end");
     157}
     158
     159void IPTVFeederHTTP::AddListener(TSDataListener *item)
     160{
     161    VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- begin");
     162    if (!item)
     163    {
     164        VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end");
     165        return;
     166    }
     167
     168    // avoid duplicates
     169    RemoveListener(item);
     170
     171    // add to local list
     172    QMutexLocker locker(&_lock);
     173    _listeners.push_back(item);
     174
     175    if (_sink)
     176        _sink->AddListener(item);
     177
     178    VERBOSE(VB_RECORD, LOC + "AddListener("<<item<<") -- end");
     179}
     180
     181void IPTVFeederHTTP::RemoveListener(TSDataListener *item)
     182{
     183    VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- begin");
     184    QMutexLocker locker(&_lock);
     185    vector<TSDataListener*>::iterator it =
     186        find(_listeners.begin(), _listeners.end(), item);
     187
     188    if (it == _listeners.end())
     189    {
     190        VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end 1");
     191        return;
     192    }
     193
     194    // remove from local list..
     195    *it = *_listeners.rbegin();
     196    _listeners.resize(_listeners.size() - 1);
     197
     198    if (_sink)
     199        _sink->RemoveListener(item);
     200
     201    VERBOSE(VB_RECORD, LOC + "RemoveListener("<<item<<") -- end 2");
     202}
  • iptv/iptvfeederhttp.h

     
     1/** -*- Mode: c++ -*-
     2 *  IPTVFeederHTTP -- basic feeder for elementary streams over HTTP (aka internet radio)
     3 *
     4 *  It generates a valid DVB-IPTV SPTS with optional SI (only the minimum
     5 *  SI as required by TS 101 154 is provided) from the received elementary
     6 *  stream. (not yet)
     7 *
     8 *  Copyright (c) 2008 by Karl Dietz
     9 *  Copyright (c) 2006 by Mike Mironov & Mickaël Remars
     10 *  Distributed as part of MythTV under GPL v2 and later.
     11 */
     12
     13#ifndef _IPTV_FEEDER_HTTP_H_
     14#define _IPTV_FEEDER_HTTP_H_
     15
     16// MythTV headers
     17#include "iptvfeederlive.h"
     18
     19class MP3HTTPSource;
     20class MPEG2TransportStreamFromESSource;
     21class IPTVMediaSink;
     22
     23
     24class IPTVFeederHTTP : public IPTVFeederLive
     25{
     26  public:
     27    IPTVFeederHTTP();
     28    virtual ~IPTVFeederHTTP();
     29
     30    bool CanHandle(const QString &url) const { return IsHTTP(url); }
     31    bool IsOpen(void) const { return _source; }
     32
     33    bool Open(const QString &url);
     34    void Close(void);
     35
     36    void AddListener(TSDataListener*);
     37    void RemoveListener(TSDataListener*);
     38
     39    static bool IsHTTP(const QString &url);
     40
     41  private:
     42    MP3HTTPSource *_source;
     43    MPEG2TransportStreamFromESSource *_multiplexor;
     44    IPTVMediaSink  *_sink;
     45
     46    int _ICY_MetadataInt;
     47
     48    /* DVB Triplet for fake DVB-SI */
     49
     50    /** original network id, private range 0xFF00 - 0xFFFE, 255 ids starting at 0xff00 */
     51    int _onid;
     52    /**
     53     * network id, private range 0xFF01 - 0xFFFF, 255 ids starting at 0xff01
     54     *
     55     * Notice the offset, according to EN 300 468 these should be the
     56     * same in case the NIT is transmitted on the origin network.
     57     * At the DVB registry the nid is not a superset of the onid!
     58     *
     59     * In our case onid and nid should be equal.
     60     */
     61    int _nid;
     62    /** transport id, choose as you see fit
     63     *
     64     * Best would be to use one tid per source location. e.g. use the CRC16 of the stream URL.
     65     *
     66     */
     67    int _tid;
     68    /** service id, choose as you see fit */
     69    int _sid;
     70
     71};
     72
     73#endif // _IPTV_FEEDER_HTTP_H_
  • iptv/iptvfeederwrapper.cpp

     
    1616#include "iptvfeederudp.h"
    1717#include "iptvfeederrtp.h"
    1818#include "iptvfeederfile.h"
     19#include "iptvfeederhttp.h"
    1920#include "libmyth/mythcontext.h"
    2021#include "libmythdb/mythverbose.h"
    2122
     
    7071    {
    7172        tmp_feeder = new IPTVFeederFile();
    7273    }
     74    else if (IPTVFeederHTTP::IsHTTP(url))
     75    {
     76        tmp_feeder = new IPTVFeederHTTP();
     77    }
    7378    else
    7479    {
    7580        VERBOSE(VB_RECORD, LOC_ERR +
  • iptv/README.HTTP

     
     1Source to capture MP3 Elementary streams from HTTP sources (aka Internet Radio Streams)
     2Point the playlist to the final stream, not some playlist as these won't get resolved.
     3
     4========= Example playlist.m3u ==========
     5= created from http://web.ard.de/radio/radionet/liste.php?ressort=alle
     6= find them also on http://www.lyngsat.com/astra1h.html
     7= NID 1
     8= TID 1093
     9= SID 28475 (1LIVE), 28402 (Bayern 3), 28432 (MDR JUMP)
     10#EXTM3U
     11#EXTINF:0,1 - 1LIVE
     12http://gffstream.ic.llnwd.net/stream/gffstream_stream_wdr_einslive_a
     13#EXTINF:0,2 - Bayern 3
     14http://gffstream.ic.llnwd.net/stream/gffstream_w12a
     15#EXTINF:0,3 - MDR JUMP
     16http://c22033-l.i.core.cdn.streamfarm.net/22004mdrjump/live/3087mdr_jump/live_de_128.mp3
  • libmythtv.pro

     
    442442        HEADERS += iptv/iptvfeederrtsp.h      iptv/iptvfeederudp.h
    443443        HEADERS += iptv/iptvfeederfile.h      iptv/iptvfeederlive.h
    444444        HEADERS += iptv/iptvfeederrtp.h       iptv/timeoutedtaskscheduler.h
     445        HEADERS += iptv/iptvfeederhttp.h
    445446
    446447        SOURCES += iptvchannel.cpp            iptvrecorder.cpp
    447448        SOURCES += iptvsignalmonitor.cpp
     
    451452        SOURCES += iptv/iptvfeederrtsp.cpp    iptv/iptvfeederudp.cpp
    452453        SOURCES += iptv/iptvfeederfile.cpp    iptv/iptvfeederlive.cpp
    453454        SOURCES += iptv/iptvfeederrtp.cpp     iptv/timeoutedtaskscheduler.cpp
     455        SOURCES += iptv/iptvfeederhttp.cpp
    454456
    455457        DEFINES += USING_IPTV
    456458    }