Exemple #1
0
static int
rtmp_probe(const char *url0, char *errbuf, size_t errlen, int timeout_ms)
{
  RTMP *r;
  char *url = mystrdupa(url0);

  r = RTMP_Alloc();
  RTMP_Init(r, NULL);

  if(!RTMP_SetupURL(r, url)) {
    snprintf(errbuf, errlen, "Unable to setup RTMP-session");
    RTMP_Free(r);
    return BACKEND_PROBE_FAIL;
  }

  if(!RTMP_Connect(r, NULL, errbuf, errlen, timeout_ms)) {
    RTMP_Close(r);
    RTMP_Free(r);
    return BACKEND_PROBE_FAIL;
  }

  RTMP_SetReadTimeout(r, timeout_ms);

  if(!RTMP_ConnectStream(r, 0)) {
    snprintf(errbuf, errlen, "Unable to connect RTMP-stream");
    RTMP_Close(r);
    RTMP_Free(r);
    return BACKEND_PROBE_FAIL;
  }

  RTMP_Close(r);
  RTMP_Free(r);

  return BACKEND_PROBE_OK;
}
Exemple #2
0
static gboolean
gst_rtmp_sink_start (GstBaseSink * basesink)
{
  GstRTMPSink *sink = GST_RTMP_SINK (basesink);

  if (!sink->uri) {
    GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE,
        ("Please set URI for RTMP output"), ("No URI set before starting"));
    return FALSE;
  }

  sink->rtmp_uri = g_strdup (sink->uri);
  sink->rtmp = RTMP_Alloc ();
  RTMP_Init (sink->rtmp);
  if (!RTMP_SetupURL (sink->rtmp, sink->rtmp_uri)) {
    GST_ELEMENT_ERROR (sink, RESOURCE, OPEN_WRITE, (NULL),
        ("Failed to setup URL '%s'", sink->uri));
    RTMP_Free (sink->rtmp);
    sink->rtmp = NULL;
    g_free (sink->rtmp_uri);
    sink->rtmp_uri = NULL;
    return FALSE;
  }

  GST_DEBUG_OBJECT (sink, "Created RTMP object");

  /* Mark this as an output connection */
  RTMP_EnableWrite (sink->rtmp);

  sink->first = TRUE;

  return TRUE;
}
/*
 * Class:     net_butterflytv_rtmp_client_RtmpClient
 * Method:    open
 * Signature: (Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_net_ossrs_sea_RtmpClient_open
        (JNIEnv * env, jobject thiz, jstring url_, jboolean isPublishMode) {

    const char *url = (*env)->GetStringUTFChars(env, url_, 0);
    rtmp = RTMP_Alloc();
    if (rtmp == NULL) {
        return -1;
    }

	RTMP_Init(rtmp);
	int ret = RTMP_SetupURL(rtmp, url);

    if (!ret) {
        RTMP_Free(rtmp);
        return -2;
    }
    if (isPublishMode) {
        RTMP_EnableWrite(rtmp);
    }

	ret = RTMP_Connect(rtmp, NULL);
    if (!ret) {
        RTMP_Free(rtmp);
        return -3;
    }
	ret = RTMP_ConnectStream(rtmp, 0);

    if (!ret) {
        return -4;
    }
    (*env)->ReleaseStringUTFChars(env, url_, url);
    return 1;
}
Exemple #4
0
static event_t *
rtmp_playvideo(const char *url0, media_pipe_t *mp,
	       int flags, int priority,
	       char *errbuf, size_t errlen,
	       const char *mimetype)
{
  rtmp_t r = {0};
  event_t *e;
  char *url = mystrdupa(url0);

  prop_set_string(mp->mp_prop_type, "video");

  RTMP_LogSetLevel(RTMP_LOGINFO);

  r.r = RTMP_Alloc();
  RTMP_Init(r.r);

  if(!RTMP_SetupURL(r.r, url)) {
    snprintf(errbuf, errlen, "Unable to setup RTMP-session");
    rtmp_free(&r);
    return NULL;
  }

  if(!RTMP_Connect(r.r, NULL)) {
    snprintf(errbuf, errlen, "Unable to connect RTMP-session");
    rtmp_free(&r);
    return NULL;
  }

  if(!RTMP_ConnectStream(r.r, 0)) {
    snprintf(errbuf, errlen, "Unable to connect RTMP-stream");
    rtmp_free(&r);
    return NULL;
  }

  mp->mp_audio.mq_stream = 0;
  mp->mp_video.mq_stream = 0;

  mp_configure(mp, MP_PLAY_CAPS_PAUSE, MP_BUFFER_DEEP);
  mp->mp_max_realtime_delay = (r.r->Link.timeout - 1) * 1000000;

  mp_become_primary(mp);

  e = rtmp_loop(&r, mp, url, errbuf, errlen);

  mp_flush(mp, 0);
  mp_shutdown(mp);

  TRACE(TRACE_DEBUG, "RTMP", "End of stream");

  rtmp_free(&r);
  return e;
}
Exemple #5
0
int main(int argc, char **argv)
{
    RTMP *rtmp=RTMP_Alloc();

    if(!rtmp)
        return 1;

    RTMP_Init(rtmp);
    RTMP_Free(rtmp);

    return 0;
}
/* open the file, do stuff necessary to go to PAUSED state */
static gboolean
gst_rtmp_src_start (GstBaseSrc * basesrc)
{
  GstRTMPSrc *src;

  src = GST_RTMP_SRC (basesrc);

  if (!src->uri) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("No filename given"));
    return FALSE;
  }

  src->cur_offset = 0;
  src->last_timestamp = 0;
  src->discont = TRUE;

  src->rtmp = RTMP_Alloc ();

  if (!src->rtmp) {
    GST_ERROR_OBJECT (src, "Could not allocate librtmp's RTMP context");
    goto error;
  }

  RTMP_Init (src->rtmp);
  if (!RTMP_SetupURL (src->rtmp, src->uri)) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
        ("Failed to setup URL '%s'", src->uri));
    goto error;
  }
  src->seekable = !(src->rtmp->Link.lFlags & RTMP_LF_LIVE);
  GST_INFO_OBJECT (src, "seekable %d", src->seekable);

  /* open if required */
  if (!RTMP_IsConnected (src->rtmp)) {
    if (!RTMP_Connect (src->rtmp, NULL)) {
      GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
          ("Could not connect to RTMP stream \"%s\" for reading", src->uri));
      goto error;
    }
  }

  return TRUE;

error:
  if (src->rtmp) {
    RTMP_Free (src->rtmp);
    src->rtmp = NULL;
  }
  return FALSE;
}
Exemple #7
0
static CURLcode rtmp_setup_connection(struct connectdata *conn)
{
  RTMP *r = RTMP_Alloc();
  if(!r)
    return CURLE_OUT_OF_MEMORY;

  RTMP_Init(r);
  RTMP_SetBufferMS(r, DEF_BUFTIME);
  if(!RTMP_SetupURL(r, conn->data->change.url)) {
    RTMP_Free(r);
    return CURLE_URL_MALFORMAT;
  }
  conn->proto.generic = r;
  return CURLE_OK;
}
Exemple #8
0
Rtmp::Rtmp(QUrl url, QObject *parent)
: QObject(parent)
{
    m_rtmp = RTMP_Alloc();
    RTMP_Init(m_rtmp);
    qDebug() << "Connecting to" << url;
    RTMP_SetupURL(m_rtmp, MY_URL );
    RTMP_EnableWrite(m_rtmp);

    RTMP_Connect(m_rtmp, NULL);
    RTMP_ConnectStream(m_rtmp, 0);
    memset(&m_rtmpPacket, 0, sizeof(RTMPPacket));
    qDebug() << RTMP_IsConnected(m_rtmp);



}
Exemple #9
0
/* open the file, do stuff necessary to go to PAUSED state */
static gboolean
gst_rtmp_src_start (GstBaseSrc * basesrc)
{
  GstRTMPSrc *src;
  gchar *uri_copy;

  src = GST_RTMP_SRC (basesrc);

  if (!src->uri) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("No filename given"));
    return FALSE;
  }

  src->cur_offset = 0;
  src->last_timestamp = 0;
  src->seekable = TRUE;
  src->discont = TRUE;

  uri_copy = g_strdup (src->uri);
  src->rtmp = RTMP_Alloc ();
  RTMP_Init (src->rtmp);
  if (!RTMP_SetupURL (src->rtmp, uri_copy)) {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
        ("Failed to setup URL '%s'", src->uri));
    g_free (uri_copy);
    RTMP_Free (src->rtmp);
    src->rtmp = NULL;
    return FALSE;
  }

  /* open if required */
  if (!RTMP_IsConnected (src->rtmp)) {
    if (!RTMP_Connect (src->rtmp, NULL)) {
      GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
          ("Could not connect to RTMP stream \"%s\" for reading", src->uri));
      RTMP_Free (src->rtmp);
      src->rtmp = NULL;
      return FALSE;
    }
  }

  return TRUE;
}
LibRtmp::LibRtmp(bool isNeedLog, bool isNeedRecord)
{
    if (isNeedLog)
    {
        flog_ = fopen("librtmp.log", "w");
        RTMP_LogSetLevel(RTMP_LOGDEBUG2);
        RTMP_LogSetOutput(flog_);
    }
    else
    {
        flog_ = NULL;
    }

    rtmp_ = RTMP_Alloc();
    RTMP_Init(rtmp_);
    RTMP_SetBufferMS(rtmp_, 300);

    streming_url_ = NULL;
    is_need_record_ = isNeedRecord;
}
int RtmpSessionHandshake(RTMP_SESSION *pSession)
{
	int iRet = 0;
	RTMPPacket *packet = (RTMPPacket *)malloc(sizeof(RTMPPacket));
	if(NULL == packet)
	{
		
		return ERROR_FAILED;
	}
	RTMPPacket_Init(packet);
	pSession->pPkt = packet;
	
	RTMP *rtmp = RTMP_Alloc(); 
	if(NULL == rtmp )
	{
		return ERROR_FAILED;
	}

	RTMP_Init(rtmp);
	rtmp->m_sb.sb_socket =  pSession->socket;
	pSession->prtmp = rtmp;

	pSession->state = RTMPSERVER_STATE_INIT;
	
	/* 进行握手处理 */
	if(RTMP_Serve(rtmp))
	{
		RTMPPacket_Free(pSession->pPkt);
		RTMPPacket_Init(pSession->pPkt);
		pSession->handshake = 1;
		pSession->arglen = 0;
		SetNonBlocking(pSession->socket);
	}
	else
	{
		iRet = -1;
	}
	
	return iRet;
}
bool RTMPWriter::initialize() {

  if(!settings.url.size()) {
    printf("error: cannot initialize the RTMP Writer, no url set, call setURL() first.\n");
    return false;
  }

  if(state == RW_STATE_INITIALIZED) {
    printf("error: already initialized.\n");
    return false;
  }

  if(rtmp) {
    printf("error: already initialized a rtmp context, not creating another one!\n");
    ::exit(EXIT_FAILURE);
  }

  rtmp = RTMP_Alloc();
  if(!rtmp) {
    printf("error: cannot allocate the rtmp context.\n");
    ::exit(EXIT_FAILURE);
  }

  RTMP_Init(rtmp);

  if(!RTMP_SetupURL(rtmp, (char*)settings.url.c_str())) {
    printf("error: cannot setup the url for the RTMP Writer.\n");
    RTMP_Free(rtmp);
    rtmp = NULL;
    return false;
  }

  if(settings.username.size()) {
    rtmp->Link.pubUser.av_val = (char*)settings.username.c_str();
    rtmp->Link.pubUser.av_len = settings.username.size();
  }

  if(settings.password.size()) {
    rtmp->Link.pubPasswd.av_val = (char*)settings.password.c_str();
    rtmp->Link.pubPasswd.av_len = settings.password.size();
  }

  rtmp->Link.flashVer.av_val = (char*)"FMLE/3.0 (compatible; FMSc/1.0)"; // when streaming to a FMS you need this!
  rtmp->Link.flashVer.av_len = (int)strlen(rtmp->Link.flashVer.av_val);

  RTMP_EnableWrite(rtmp);

  if(!RTMP_Connect(rtmp, NULL)) {
    printf("error: cannot connect to the rtmp server: %s\n", settings.url.c_str());
    RTMP_Free(rtmp);
    rtmp = NULL;
    /*
    if(state == RW_STATE_RECONNECTING) {
      state = RW_STATE_NONE;
      printf("@todo need to call the disconnect callback.\n");
      //reconnect(); 
     }
    */

    return false;
  }

  if(!RTMP_ConnectStream(rtmp, 0)) {
    printf("error: cannot connect to the rtmp stream on %s.\n", settings.url.c_str());
    RTMP_Free(rtmp);
    rtmp = NULL;

    if(state == RW_STATE_RECONNECTING) {
      state = RW_STATE_NONE;
      // reconnect(); 
    }

    return false;
  }

  state = RW_STATE_INITIALIZED;

  return true;
}
Exemple #13
0
int main (int argc, char **argv) {
	char *url;
	int brate = 32;
	int c;
	while ((c = getopt(argc, argv, "u:b:")) != -1)
		switch (c) {
			case 'u':
				url = strdup(optarg);
				break;
			case 'b':
				brate = atoi(optarg);
				break;
			default:
				abort();
		}
// libev
	loop = ev_default_loop(0);
	ev_signal_init(&sigint_sig, sigint_cb, SIGINT);
	ev_signal_start (loop, &sigint_sig);
	ev_async_init(&async, send_cb);
	ev_async_start(loop, &async);

// jack
	jack_status_t status;
	ringbuf = jack_ringbuffer_create(buffer_size);
	framebuf = malloc(buffer_samples * sizeof(jack_default_audio_sample_t));
	client = jack_client_open("jack2rtmp", JackNullOption, &status);
	if (client == NULL) {
		fprintf(stderr, "jack server not running?\n");
		return EXIT_FAILURE;
	}
	jack_on_shutdown(client, jack_shutdown, NULL);
	jack_set_process_callback(client, jack_callback, NULL);
	//jack_set_latency_callback(client, jack_latency_callback, NULL);
	output_port = jack_port_register(client, "1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
	//jack_port_register(client, "2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
	if (jack_activate(client)) {
		fprintf(stderr, "cannot activate client");
	}

// lame
	mp3 = lame_init();
	lame_set_num_channels(mp3, 1);
	lame_set_mode(mp3, MONO);
	lame_set_in_samplerate(mp3, 48000);
	lame_set_out_samplerate(mp3, 44100);
	lame_set_quality(mp3, 2); // 0=best (very slow), 9=worst.
	lame_set_brate(mp3, brate);
	lame_init_params(mp3);

// rtmp
	rtmp_o = RTMP_Alloc();
	if (rtmp_o == NULL) {
		fprintf(stderr, "RTMP_Alloc\n");
		return EXIT_FAILURE;
	}
	RTMP_Init(rtmp_o);
	RTMP_SetupURL(rtmp_o, url);
	RTMP_EnableWrite(rtmp_o);
	if (!RTMP_Connect(rtmp_o, NULL) || !RTMP_ConnectStream(rtmp_o, 0)) {
		RTMP_Free(rtmp_o);
		fprintf(stderr, "Can not connect.\n");
		return EXIT_FAILURE;
	} else {
		fprintf(stderr, "Connected.\n");
	}

/*
	char *rtmp_buffer = malloc(4096);
	char *rtmp_top = rtmp_buffer + RTMP_MAX_HEADER_SIZE;
	char *outend = rtmp_buffer + 4096;
	*rtmp_top = (uint8_t) AMF_STRING;
	rtmp_top++;
	rtmp_top = put_amf_string(rtmp_top, "@setDataFrame");
	*rtmp_top = (uint8_t) AMF_STRING;
	rtmp_top++;
	rtmp_top = put_amf_string(rtmp_top, "onMetaData");

	// описание объекта
	*rtmp_top = (uint8_t) 8;
	rtmp_top++;
	rtmp_top = AMF_EncodeInt32(rtmp_top, outend, 8);
	// содержимое объекта
	rtmp_top = put_amf_string(rtmp_top, "duration");
	rtmp_top = AMF_EncodeNumber(rtmp_top, outend, 0);
	rtmp_top = put_amf_string(rtmp_top, "audiodatarate");
	rtmp_top = AMF_EncodeNumber(rtmp_top, outend, brate);
	rtmp_top = put_amf_string(rtmp_top, "audiosamplerate");
	rtmp_top = AMF_EncodeNumber(rtmp_top, outend, 44100);
	rtmp_top = put_amf_string(rtmp_top, "audiosamplesize");
	rtmp_top = AMF_EncodeNumber(rtmp_top, outend, 16);
	rtmp_top = put_amf_string(rtmp_top, "stereo");
	rtmp_top = AMF_EncodeBoolean(rtmp_top, outend, FALSE);
	rtmp_top = put_amf_string(rtmp_top, "audiocodecid");
	rtmp_top = AMF_EncodeNumber(rtmp_top, outend, 2);
	rtmp_top = put_amf_string(rtmp_top, "encoder");
	*rtmp_top = (uint8_t) AMF_STRING;
	rtmp_top++;
	rtmp_top = put_amf_string(rtmp_top, "Lavf53.21.1");
	rtmp_top = put_amf_string(rtmp_top, "filesize");
	rtmp_top = AMF_EncodeNumber(rtmp_top, outend, 0);
	// конец объекта
	rtmp_top = put_amf_string(rtmp_top, "");
	*rtmp_top = (uint8_t) AMF_OBJECT_END;
	rtmp_top++;

	rtmp_w.m_headerType = RTMP_PACKET_SIZE_LARGE;
	rtmp_w.m_nChannel = 0x04; // source channel
	rtmp_w.m_nBodySize = rtmp_top - rtmp_buffer - RTMP_MAX_HEADER_SIZE;
	rtmp_w.m_packetType = RTMP_PACKET_TYPE_INFO;
	rtmp_w.m_nInfoField2 = rtmp_o->m_stream_id;
	rtmp_w.m_body = rtmp_buffer + RTMP_MAX_HEADER_SIZE;
	if ( !RTMP_SendPacket(rtmp_o, &rtmp_w, TRUE) ) {
		fprintf(stderr, "RTMP_SendPacket error\n");
	}
	free(rtmp_buffer);
*/

	int off = 0;
	setsockopt(RTMP_Socket(rtmp_o), SOL_TCP, TCP_NODELAY, &off, sizeof(off));




	rtmp_i = TRUE;
	ev_loop(loop, 0);


	jack_ringbuffer_free(ringbuf);
	//jack_client_close(client);
	return EXIT_SUCCESS;
}
Exemple #14
0
DWORD WINAPI RTMPPublisher::CreateConnectionThread(RTMPPublisher *publisher)
{
    //------------------------------------------------------
    // set up URL

    bool bRetry = false;
    bool bSuccess = false;
    bool bCanRetry = false;

    String failReason;
    String strBindIP;

    int    serviceID    = AppConfig->GetInt   (TEXT("Publish"), TEXT("Service"));
    String strURL       = AppConfig->GetString(TEXT("Publish"), TEXT("URL"));
    String strPlayPath  = AppConfig->GetString(TEXT("Publish"), TEXT("PlayPath"));

    strURL.KillSpaces();
    strPlayPath.KillSpaces();

    LPSTR lpAnsiURL = NULL, lpAnsiPlaypath = NULL;
    RTMP *rtmp = NULL;

    //--------------------------------
    // unbelievably disgusting hack for elgato devices

    String strOldDirectory;
    UINT dirSize = GetCurrentDirectory(0, 0);
    strOldDirectory.SetLength(dirSize);
    GetCurrentDirectory(dirSize, strOldDirectory.Array());

    OSSetCurrentDirectory(API->GetAppPath());

    //--------------------------------

    if(!strURL.IsValid())
    {
        failReason = TEXT("No server specified to connect to");
        goto end;
    }

    if(serviceID != 0)
    {
        XConfig serverData;
        if(!serverData.Open(TEXT("services.xconfig")))
        {
            failReason = TEXT("Could not open services.xconfig");
            goto end;
        }

        XElement *services = serverData.GetElement(TEXT("services"));
        if(!services)
        {
            failReason = TEXT("Could not find any services in services.xconfig");
            goto end;
        }

        XElement *service = NULL;
        DWORD numServices = services->NumElements();
        for(UINT i=0; i<numServices; i++)
        {
            XElement *curService = services->GetElementByID(i);
            if(curService->GetInt(TEXT("id")) == serviceID)
            {
                service = curService;
                break;
            }
        }

        if(!service)
        {
            failReason = TEXT("Could not find the service specified in services.xconfig");
            goto end;
        }

        XElement *servers = service->GetElement(TEXT("servers"));
        if(!servers)
        {
            failReason = TEXT("Could not find any servers for the service specified in services.xconfig");
            goto end;
        }

        XDataItem *item = servers->GetDataItem(strURL);
        if(!item)
            item = servers->GetDataItemByID(0);

        strURL = item->GetData();

        Log(TEXT("Using RTMP service: %s"), service->GetName());
        Log(TEXT("  Server selection: %s"), strURL.Array());
    }

    //------------------------------------------------------
    // now back to the elgato directory if it needs the directory changed still to function *sigh*

    OSSetCurrentDirectory(strOldDirectory);

    //------------------------------------------------------

    rtmp = RTMP_Alloc();
    RTMP_Init(rtmp);

    RTMP_LogSetCallback(librtmpErrorCallback);

    //RTMP_LogSetLevel(RTMP_LOGERROR);

    lpAnsiURL = strURL.CreateUTF8String();
    lpAnsiPlaypath = strPlayPath.CreateUTF8String();

    if(!RTMP_SetupURL2(rtmp, lpAnsiURL, lpAnsiPlaypath))
    {
        failReason = Str("Connection.CouldNotParseURL");
        goto end;
    }

    char *rtmpUser = AppConfig->GetString(TEXT("Publish"), TEXT("Username")).CreateUTF8String();
    char *rtmpPass = AppConfig->GetString(TEXT("Publish"), TEXT("Password")).CreateUTF8String();

    if (rtmpUser)
    {
        rtmp->Link.pubUser.av_val = rtmpUser;
        rtmp->Link.pubUser.av_len = (int)strlen(rtmpUser);
    }

    if (rtmpPass)
    {
        rtmp->Link.pubPasswd.av_val = rtmpPass;
        rtmp->Link.pubPasswd.av_len = (int)strlen(rtmpPass);
    }

    RTMP_EnableWrite(rtmp); //set it to publish

    rtmp->Link.swfUrl.av_len = rtmp->Link.tcUrl.av_len;
    rtmp->Link.swfUrl.av_val = rtmp->Link.tcUrl.av_val;
    /*rtmp->Link.pageUrl.av_len = rtmp->Link.tcUrl.av_len;
    rtmp->Link.pageUrl.av_val = rtmp->Link.tcUrl.av_val;*/
    rtmp->Link.flashVer.av_val = "FMLE/3.0 (compatible; FMSc/1.0)";
    rtmp->Link.flashVer.av_len = (int)strlen(rtmp->Link.flashVer.av_val);

    //-----------------------------------------

    UINT tcpBufferSize = AppConfig->GetInt(TEXT("Publish"), TEXT("TCPBufferSize"), 64*1024);

    if(tcpBufferSize < 8192)
        tcpBufferSize = 8192;
    else if(tcpBufferSize > 1024*1024)
        tcpBufferSize = 1024*1024;

    rtmp->m_outChunkSize = 4096;//RTMP_DEFAULT_CHUNKSIZE;//
    rtmp->m_bSendChunkSizeInfo = TRUE;

    rtmp->m_bUseNagle = TRUE;

    strBindIP = AppConfig->GetString(TEXT("Publish"), TEXT("BindToIP"), TEXT("Default"));
    if (scmp(strBindIP, TEXT("Default")))
    {
        rtmp->m_bindIP.addr.sin_family = AF_INET;
        rtmp->m_bindIP.addrLen = sizeof(rtmp->m_bindIP.addr);
        if (WSAStringToAddress(strBindIP.Array(), AF_INET, NULL, (LPSOCKADDR)&rtmp->m_bindIP.addr, &rtmp->m_bindIP.addrLen) == SOCKET_ERROR)
        {
            // no localization since this should rarely/never happen
            failReason = TEXT("WSAStringToAddress: Could not parse address");
            goto end;
        }
    }

    LogInterfaceType(rtmp);

    //-----------------------------------------

    if(!RTMP_Connect(rtmp, NULL))
    {
        failReason = Str("Connection.CouldNotConnect");
        failReason << TEXT("\r\n\r\n") << RTMPPublisher::GetRTMPErrors();
        bCanRetry = true;
        goto end;
    }

    if(!RTMP_ConnectStream(rtmp, 0))
    {
        failReason = Str("Connection.InvalidStream");
        failReason << TEXT("\r\n\r\n") << RTMPPublisher::GetRTMPErrors();
        bCanRetry = true;
        goto end;
    }

    //-----------------------------------------

    OSDebugOut(TEXT("Connected: %u\r\n"), OSGetTime());

    publisher->RequestKeyframe(1000);

    //-----------------------------------------

    bSuccess = true;

end:

    if (lpAnsiURL)
        Free(lpAnsiURL);

    if (lpAnsiPlaypath)
        Free(lpAnsiPlaypath);

    if(!bSuccess)
    {
        if(rtmp)
        {
            RTMP_Close(rtmp);
            RTMP_Free(rtmp);
        }

        if(failReason.IsValid())
            App->SetStreamReport(failReason);

        if(!publisher->bStopping)
            PostMessage(hwndMain, OBS_REQUESTSTOP, bCanRetry ? 0 : 1, 0);

        Log(TEXT("Connection to %s failed: %s"), strURL.Array(), failReason.Array());

        publisher->bStopping = true;
    }
    else
    {
        publisher->Init(rtmp, tcpBufferSize);
        publisher->bConnected = true;
        publisher->bConnecting = false;
    }

    return 0;
}
Exemple #15
0
static event_t *
rtmp_playvideo(const char *url0, media_pipe_t *mp,
	       int flags, int priority,
	       char *errbuf, size_t errlen,
	       const char *mimetype,
	       const char *canonical_url)
{
  rtmp_t r = {0};
  event_t *e;
  char *url = mystrdupa(url0);

  prop_set_string(mp->mp_prop_type, "video");

  RTMP_LogSetLevel(RTMP_LOGINFO);

  r.r = RTMP_Alloc();
  RTMP_Init(r.r);

  int64_t start = video_get_restartpos(canonical_url);

  if(!RTMP_SetupURL(r.r, url)) {
    snprintf(errbuf, errlen, "Unable to setup RTMP-session");
    rtmp_free(&r);
    return NULL;
  }

  if(!RTMP_Connect(r.r, NULL)) {
    snprintf(errbuf, errlen, "Unable to connect RTMP-session");
    rtmp_free(&r);
    return NULL;
  }

  if(!RTMP_ConnectStream(r.r, start)) {
    snprintf(errbuf, errlen, "Unable to connect RTMP-stream");
    rtmp_free(&r);
    return NULL;
  }
  r.seek_origin = start;
  r.mp = mp;
  r.hold = 0;
  r.lost_focus = 0;
  r.epoch = 1;
  
  mp->mp_audio.mq_stream = 0;
  mp->mp_video.mq_stream = 0;

  if(start > 0) {
    r.seekpos = start * 1000;
    r.seekbase = r.seekpos;
    mp->mp_video.mq_seektarget = r.seekpos;
    mp->mp_audio.mq_seektarget = r.seekpos;
  } else {
    mp->mp_video.mq_seektarget = AV_NOPTS_VALUE;
    mp->mp_audio.mq_seektarget = AV_NOPTS_VALUE;
    r.seekbase = AV_NOPTS_VALUE;
    r.seekpos = AV_NOPTS_VALUE;
  }

  mp_configure(mp, MP_PLAY_CAPS_PAUSE, MP_BUFFER_DEEP);
  mp->mp_max_realtime_delay = (r.r->Link.timeout - 1) * 1000000;

  mp_become_primary(mp);

  metadb_register_play(canonical_url, 0, CONTENT_VIDEO);

  r.canonical_url = canonical_url;
  r.restartpos_last = -1;

  e = rtmp_loop(&r, mp, url, errbuf, errlen);

  if(r.total_duration) {
    int p = r.seekbase / (r.total_duration * 10);
    if(p >= video_settings.played_threshold) {
      TRACE(TRACE_DEBUG, "RTMP", "Playback reached %d%%, counting as played",
	    p);
      metadb_register_play(canonical_url, 1, CONTENT_VIDEO);
      metadb_set_video_restartpos(canonical_url, -1);
    }
  }

  mp_flush(mp, 0);
  mp_shutdown(mp);

  TRACE(TRACE_DEBUG, "RTMP", "End of stream");

  rtmp_free(&r);
  return e;
}
Exemple #16
0
static event_t *
rtmp_playvideo(const char *url0, media_pipe_t *mp,
	       char *errbuf, size_t errlen,
	       video_queue_t *vq, struct vsource_list *vsl,
	       const video_args_t *va0)
{
  video_args_t va = *va0;
  rtmp_t r = {0};
  event_t *e;
  char *url = mystrdupa(url0);

  mp_set_url(mp, va0->canonical_url, va0->parent_url, va0->parent_title);

  usage_event("Play video", 1, USAGE_SEG("format", "RTMP"));

  prop_set(mp->mp_prop_metadata, "format", PROP_SET_STRING, "RTMP");
  prop_set(mp->mp_prop_root, "loading", PROP_SET_INT, 1);

  va.flags |= BACKEND_VIDEO_NO_FS_SCAN;

  rtmp_log_level = RTMP_LOGINFO;
  RTMP_LogSetLevel(rtmp_log_level);

  r.r = RTMP_Alloc();
  RTMP_Init(r.r, mp->mp_cancellable);

  int64_t start = playinfo_get_restartpos(va.canonical_url, va.title, va.resume_mode);

  if(!RTMP_SetupURL(r.r, url)) {
    snprintf(errbuf, errlen, "Unable to setup RTMP-session");
    rtmp_free(&r);
    return NULL;
  }

  r.r->Link.lFlags |= RTMP_LF_SWFV;

  if(!RTMP_Connect(r.r, NULL, errbuf, errlen, 5000)) {
    rtmp_free(&r);
    return NULL;
  }

  if(!RTMP_ConnectStream(r.r, 0)) {
    snprintf(errbuf, errlen, "Unable to connect RTMP-stream");
    rtmp_free(&r);
    return NULL;
  }

  if(start)
    RTMP_SendSeek(r.r, start);
    
  r.mp = mp;
  
  mp->mp_audio.mq_stream = 0;
  mp->mp_video.mq_stream = 0;

  if(start > 0) {
    r.seekpos_video = start * 1000;
    r.seekpos_audio = start * 1000;
    mp->mp_seek_base = r.seekpos_video;
    mp->mp_video.mq_seektarget = r.seekpos_video;
    mp->mp_audio.mq_seektarget = r.seekpos_video;
  } else {
    mp->mp_video.mq_seektarget = AV_NOPTS_VALUE;
    mp->mp_audio.mq_seektarget = AV_NOPTS_VALUE;
    mp->mp_seek_base = 0;
    r.seekpos_audio = AV_NOPTS_VALUE;
    r.seekpos_video = AV_NOPTS_VALUE;
  }

  mp_configure(mp, MP_CAN_PAUSE, MP_BUFFER_DEEP, 0, "video");
  mp->mp_max_realtime_delay = (r.r->Link.timeout - 1) * 1000000;

  mp_become_primary(mp);

  playinfo_register_play(va.canonical_url, 0);

  r.canonical_url = va.canonical_url;
  r.restartpos_last = -1;

  r.url = url;
  r.va = &va;
  r.is_loading = 1;
  e = rtmp_loop(&r, mp, url, errbuf, errlen);

  if(r.ss)
    sub_scanner_destroy(r.ss);

  if(r.total_duration) {
    int p = mp->mp_seek_base / (r.total_duration * 10);
    if(p >= video_settings.played_threshold) {
      TRACE(TRACE_DEBUG, "RTMP", "Playback reached %d%%, counting as played",
	    p);
      playinfo_register_play(va.canonical_url, 1);
      playinfo_set_restartpos(va.canonical_url, -1, 0);
    } else {
      playinfo_set_restartpos(va.canonical_url, mp->mp_seek_base / 1000, 0);
    }
  }

  mp_shutdown(mp);

  TRACE(TRACE_DEBUG, "RTMP", "End of playback");

  rtmp_free(&r);
  return e;
}
Exemple #17
0
int main(int argc, char *argv[])
{
	struct stat sb;
	int opt, i;
	int chapter = 0, available = 0;
	char *book = NULL;
	char audio[256];
	
	while ((opt = getopt(argc, argv, "v:a:b:c:l")) != -1) {
		switch (opt) {
			case 'v':
				version = optarg;
				break;
			case 'a':
				author = optarg;
				break;
			case 'b':
				book = optarg;
				break;
			case 'c':
				chapter = atoi(optarg);
				break;
			case 'l':
				return list();
		} 
	}

	sprintf(audio, "%s-%s", version, author);
	for (i = 0; i < ARRAY_SIZE(audios); i++) {
		if (strcasecmp(audios[i].audio, audio) == 0) {
			available = 1;
			break;
		}
	}
	if (!available) {
		fprintf(stderr, "Invalid version `%s' or author `%s'\n", version, author);
		return EINVAL;
	}

	for (i = 0; i < ARRAY_SIZE(books); i++) {
		if (!book || strcasecmp(books[i].osis, book) == 0) {
			available = 1;
			break;
		}
	}

	if (!available) {
		fprintf(stderr, "Invalid book `%s'\n", book);
		return EINVAL;
	}

	if ((rtmp = RTMP_Alloc()) == NULL || (buffer = malloc(BUFSIZ)) == NULL) {
		perror("malloc");
		return ENOMEM;
	}

	if (stat(audio, &sb) == -1) {
		if (errno == ENOENT) {
			mkdir(audio, 0755);
		} else {
			perror("stat");
			return errno;
		}
	} else if (!S_ISDIR(sb.st_mode)) {
		fprintf(stderr, "%s is not a directory\n", audio);
		return errno;
	}

	if (book) {
		if (chapter > books[i].chapter) {
			fprintf(stderr, "Invalid chapter `%d'\n", chapter);
			return EINVAL;
		}
		if (chapter) {
			download(books[i].osis, chapter);
		} else {
			for (chapter = 1; chapter <= books[i].chapter; chapter++) {
				download(books[i].osis, chapter);
			}
		}
		
	} else {
		for (i = 0; i < ARRAY_SIZE(books); i++) {
			for (chapter = 1; chapter <= books[i].chapter; chapter++) {
				download(books[i].osis, chapter);
			}
		}
	}

	RTMP_Free(rtmp);
	free(buffer);

	return 0;
}
Exemple #18
0
//Publish using RTMP_SendPacket()  
int publish_using_packet(){  
	RTMP *rtmp=NULL;                             
	RTMPPacket *packet=NULL;  
	uint32_t start_time=0;  
	uint32_t now_time=0;  
	//the timestamp of the previous frame  
	long pre_frame_time=0;  
	long lasttime=0;  
	int bNextIsKey=1;  
	uint32_t preTagsize=0;  

	//packet attributes  
	uint32_t type=0;                          
	uint32_t datalength=0;             
	uint32_t timestamp=0;             
	uint32_t streamid=0;                          

	FILE*fp=NULL;  
	fp=fopen("../live.flv","rb");  
	if (!fp){  
		RTMP_LogPrintf("Open File Error.\n");  
	//	CleanupSockets();  
		return -1;  
	}  

	/* set log level */  
	//RTMP_LogLevel loglvl=RTMP_LOGDEBUG;  
	//RTMP_LogSetLevel(loglvl);  

//	if (!InitSockets()){  
//		RTMP_LogPrintf("Init Socket Err\n");  
//		return -1;  
//	}  

	rtmp=RTMP_Alloc();  
	RTMP_Init(rtmp);  
	//set connection timeout,default 30s  
	rtmp->Link.timeout=5;                        
	if(!RTMP_SetupURL(rtmp,"rtmp://101.251.251.93:1935/myapp/mystream"))  
	{  
		RTMP_Log(RTMP_LOGERROR,"SetupURL Err\n");  
		RTMP_Free(rtmp);  
	//	CleanupSockets();  
		return -1;  
	}  

	//if unable,the AMF command would be 'play' instead of 'publish'  
	RTMP_EnableWrite(rtmp);       

	if (!RTMP_Connect(rtmp,NULL)){  
		RTMP_Log(RTMP_LOGERROR,"Connect Err\n");  
		RTMP_Free(rtmp);  
	//	CleanupSockets();  
		return -1;  
	}  

	if (!RTMP_ConnectStream(rtmp,0)){  
		RTMP_Log(RTMP_LOGERROR,"ConnectStream Err\n");  
		RTMP_Close(rtmp);  
		RTMP_Free(rtmp);  
//		CleanupSockets();  
		return -1;  
	}  

	packet=(RTMPPacket*)malloc(sizeof(RTMPPacket));  
	RTMPPacket_Alloc(packet,1024*64);  
	RTMPPacket_Reset(packet);  

	packet->m_hasAbsTimestamp = 0;          
	packet->m_nChannel = 0x04;  
	packet->m_nInfoField2 = rtmp->m_stream_id;  

	RTMP_LogPrintf("Start to send data ...\n");  

	//jump over FLV Header  
	fseek(fp,9,SEEK_SET);       
	//jump over previousTagSizen  
	fseek(fp,4,SEEK_CUR);     
	start_time=RTMP_GetTime();  
	while(1)  
	{  
		if((((now_time=RTMP_GetTime())-start_time)  
					<(pre_frame_time)) && bNextIsKey){          
			//wait for 1 sec if the send process is too fast  
			//this mechanism is not very good,need some improvement  
			if(pre_frame_time>lasttime){  
				RTMP_LogPrintf("TimeStamp:%8lu ms\n",pre_frame_time);  
				lasttime=pre_frame_time;  
			}  
			sleep(1);  
			continue;  
		}  

		//not quite the same as FLV spec  
		if(!ReadU8(&type,fp))       
			break;  
		if(!ReadU24(&datalength,fp))  
			break;  
		if(!ReadTime(&timestamp,fp))  
			break;  
		if(!ReadU24(&streamid,fp))  
			break;  

		if (type!=0x08&&type!=0x09){  
			//jump over non_audio and non_video frame,  
			//jump over next previousTagSizen at the same time  
			fseek(fp,datalength+4,SEEK_CUR);  
			continue;  
		}  

		if(fread(packet->m_body,1,datalength,fp)!=datalength)  
			break;  

		packet->m_headerType = RTMP_PACKET_SIZE_LARGE;  
		packet->m_nTimeStamp = timestamp;  
		packet->m_packetType = type;  
		packet->m_nBodySize  = datalength;  
		pre_frame_time=timestamp;  

		if (!RTMP_IsConnected(rtmp)){  
			RTMP_Log(RTMP_LOGERROR,"rtmp is not connect\n");  
			break;  
		}  
		if (!RTMP_SendPacket(rtmp,packet,0)){  
			RTMP_Log(RTMP_LOGERROR,"Send Error\n");  
			break;  
		}  

		if(!ReadU32(&preTagsize,fp))  
			break;  

		if(!PeekU8(&type,fp))  
			break;  
		if(type==0x09){  
			if(fseek(fp,11,SEEK_CUR)!=0)  
				break;  
			if(!PeekU8(&type,fp)){  
				break;  
			}  
			if(type==0x17)  
				bNextIsKey=1;  
			else  
				bNextIsKey=0;  

			fseek(fp,-11,SEEK_CUR);  
		}  
	}                 

	RTMP_LogPrintf("\nSend Data Over\n");  

	if(fp)  
		fclose(fp);  

	if (rtmp!=NULL){  
		RTMP_Close(rtmp);          
		RTMP_Free(rtmp);   
		rtmp=NULL;  
	}  
	if (packet!=NULL){  
		RTMPPacket_Free(packet);      
		free(packet);  
		packet=NULL;  
	}  

//	CleanupSockets();  
	return 0;  
}  
Exemple #19
0
//Publish using RTMP_Write()  
int publish_using_write(){  
	uint32_t start_time=0;  
	uint32_t now_time=0;  
	uint32_t pre_frame_time=0;  
	uint32_t lasttime=0;  
	int bNextIsKey=0;  
	char* pFileBuf=NULL;  

	//read from tag header  
	uint32_t type=0;  
	uint32_t datalength=0;  
	uint32_t timestamp=0;  

	RTMP *rtmp=NULL;                             

	FILE*fp=NULL;  
	fp=fopen("cuc_ieschool.flv","rb");  
	if (!fp){  
		RTMP_LogPrintf("Open File Error.\n");  
//		CleanupSockets();  
		return -1;  
	}  

	/* set log level */  
	//RTMP_LogLevel loglvl=RTMP_LOGDEBUG;  
	//RTMP_LogSetLevel(loglvl);  

//	if (!InitSockets()){  
//		RTMP_LogPrintf("Init Socket Err\n");  
//		return -1;  
//	}  

	rtmp=RTMP_Alloc();  
	RTMP_Init(rtmp);  
	//set connection timeout,default 30s  
	rtmp->Link.timeout=5;                        
	if(!RTMP_SetupURL(rtmp,"rtmp://localhost/publishlive/livestream"))  
	{  
		RTMP_Log(RTMP_LOGERROR,"SetupURL Err\n");  
		RTMP_Free(rtmp);  
	//	CleanupSockets();  
		return -1;  
	}  

	RTMP_EnableWrite(rtmp);  
	//1hour  
	RTMP_SetBufferMS(rtmp, 3600*1000);           
	if (!RTMP_Connect(rtmp,NULL)){  
		RTMP_Log(RTMP_LOGERROR,"Connect Err\n");  
		RTMP_Free(rtmp);  
//		CleanupSockets();  
		return -1;  
	}  

	if (!RTMP_ConnectStream(rtmp,0)){  
		RTMP_Log(RTMP_LOGERROR,"ConnectStream Err\n");  
		RTMP_Close(rtmp);  
		RTMP_Free(rtmp);  
		//CleanupSockets();  
		return -1;  
	}  

	printf("Start to send data ...\n");  

	//jump over FLV Header  
	fseek(fp,9,SEEK_SET);       
	//jump over previousTagSizen  
	fseek(fp,4,SEEK_CUR);     
	start_time=RTMP_GetTime();  
	while(1)  
	{  
		if((((now_time=RTMP_GetTime())-start_time)  
					<(pre_frame_time)) && bNextIsKey){          
			//wait for 1 sec if the send process is too fast  
			//this mechanism is not very good,need some improvement  
			if(pre_frame_time>lasttime){  
				RTMP_LogPrintf("TimeStamp:%8lu ms\n", pre_frame_time);  
				lasttime=pre_frame_time;  
			}  
			sleep(1);  
			continue;  
		}  

		//jump over type  
		fseek(fp,1,SEEK_CUR);     
		if(!ReadU24(&datalength,fp))  
			break;  
		if(!ReadTime(&timestamp,fp))  
			break;  
		//jump back  
		fseek(fp,-8,SEEK_CUR);    

		pFileBuf=(char*)malloc(11+datalength+4);  
		memset(pFileBuf,0,11+datalength+4);  
		if(fread(pFileBuf,1,11+datalength+4,fp)!=(11+datalength+4))  
			break;  

		pre_frame_time=timestamp;  

		if (!RTMP_IsConnected(rtmp)){  
			RTMP_Log(RTMP_LOGERROR,"rtmp is not connect\n");  
			break;  
		}  
		if (!RTMP_Write(rtmp,pFileBuf,11+datalength+4)){  
			RTMP_Log(RTMP_LOGERROR,"Rtmp Write Error\n");  
			break;  
		}  

		free(pFileBuf);  
		pFileBuf=NULL;  

		if(!PeekU8(&type,fp))  
			break;  
		if(type==0x09){  
			if(fseek(fp,11,SEEK_CUR)!=0)  
				break;  
			if(!PeekU8(&type,fp)){  
				break;  
			}  
			if(type==0x17)  
				bNextIsKey=1;  
			else  
				bNextIsKey=0;  
			fseek(fp,-11,SEEK_CUR);  
		}  
	}  

	RTMP_LogPrintf("\nSend Data Over\n");  

	if(fp)  
		fclose(fp);  

	if (rtmp!=NULL){  
		RTMP_Close(rtmp);          
		RTMP_Free(rtmp);  
		rtmp=NULL;  
	}  

	if(pFileBuf){  
		free(pFileBuf);  
		pFileBuf=NULL;  
	}  

	//CleanupSockets();  
	return 0;  
}  
int main(int argc, char* argv[])
{
    InitSockets();

    double duration = -1;
    int nRead;
    //is live stream ?
    bool bLiveStream = TRUE;

    int bufsize = 1024 * 1024 * 10;
    char *buf = (char*)malloc(bufsize);
    memset(buf, 0, bufsize);
    long countbufsize = 0;

    FILE *fp = fopen("receive.flv", "wb");
    if (!fp)
    {
        RTMP_LogPrintf("Open File Error.\n");
        CleanupSockets();
        return -1;
    }

    /* set log level */
    RTMP_LogLevel loglvl = RTMP_LOGDEBUG;
    RTMP_LogSetLevel(loglvl);

    RTMP *rtmp = RTMP_Alloc();
    RTMP_Init(rtmp);
    //set connection timeout,default 30s
    rtmp->Link.timeout = 10;

	char* rtmpFilePath = "d:\\rtmp.raw";
	rtmp->m_pRTMPFile = fopen(rtmpFilePath,"rb");
	if (!rtmp->m_pRTMPFile)
	{
		RTMP_LogPrintf("Failed to open File :%s\n", rtmpFilePath);
		return FALSE;
	}

	// HKS's live URL
	if(!RTMP_SetupURL(rtmp, "rtmp://live.hkstv.hk.lxdns.com/live/hks"))
    {
        RTMP_Log(RTMP_LOGERROR, "SetupURL Err\n");
        RTMP_Free(rtmp);
        CleanupSockets();
        return -1;
    }
    if (bLiveStream)
    {
        rtmp->Link.lFlags |= RTMP_LF_LIVE;
    }

    //1hour
    RTMP_SetBufferMS(rtmp, 3600 * 1000);

    if(!RTMP_Connect(rtmp, NULL))
    {
        RTMP_Log(RTMP_LOGERROR, "Connect Err\n");
        RTMP_Free(rtmp);
        CleanupSockets();
        return -1;
    }

    if(!RTMP_ConnectStream(rtmp, 0))
    {
        RTMP_Log(RTMP_LOGERROR, "ConnectStream Err\n");
        RTMP_Close(rtmp);
        RTMP_Free(rtmp);
        CleanupSockets();
        return -1;
    }

    while(nRead = RTMP_Read(rtmp, buf, bufsize))
    {
        fwrite(buf, 1, nRead, fp);

        countbufsize += nRead;
        RTMP_LogPrintf("Receive: %5dByte, Total: %5.2fkB\n", nRead, countbufsize * 1.0 / 1024);
    }

    if(fp)
        fclose(fp);

    if(fpPcap)
        fclose(fpPcap);

	if (rtmp->m_pRTMPFile)
	{
		fclose(rtmp->m_pRTMPFile);
	}

    if(buf)
    {
        free(buf);
    }

    if(rtmp)
    {
        RTMP_Close(rtmp);
        RTMP_Free(rtmp);
        CleanupSockets();
        rtmp = NULL;
    }
    return 0;
}
Exemple #21
0
static event_t *
rtmp_playvideo(const char *url0, media_pipe_t *mp,
	       char *errbuf, size_t errlen,
	       video_queue_t *vq, struct vsource_list *vsl,
	       const video_args_t *va0)
{
  video_args_t va = *va0;
  rtmp_t r = {0};
  event_t *e;
  char *url = mystrdupa(url0);

  va.flags |= BACKEND_VIDEO_NO_FS_SCAN;

  prop_set_string(mp->mp_prop_type, "video");

  rtmp_log_level = RTMP_LOGINFO;
  RTMP_LogSetLevel(rtmp_log_level);

  r.r = RTMP_Alloc();
  RTMP_Init(r.r);

  int64_t start = 0;

  if(va.flags & BACKEND_VIDEO_RESUME ||
     (video_settings.resume_mode == VIDEO_RESUME_YES &&
      !(va.flags & BACKEND_VIDEO_START_FROM_BEGINNING)))
    start = video_get_restartpos(va.canonical_url);

  if(!RTMP_SetupURL(r.r, url)) {
    snprintf(errbuf, errlen, "Unable to setup RTMP-session");
    rtmp_free(&r);
    return NULL;
  }

  r.r->Link.lFlags |= RTMP_LF_SWFV;

  if(!RTMP_Connect(r.r, NULL)) {
    snprintf(errbuf, errlen, "Unable to connect RTMP-session");
    rtmp_free(&r);
    return NULL;
  }

  if(!RTMP_ConnectStream(r.r, 0)) {
    snprintf(errbuf, errlen, "Unable to connect RTMP-stream");
    rtmp_free(&r);
    return NULL;
  }

  if(start)
    RTMP_SendSeek(r.r, start);
    
  r.mp = mp;
  
  mp->mp_audio.mq_stream = 0;
  mp->mp_video.mq_stream = 0;

  if(start > 0) {
    r.seekpos_video = start * 1000;
    r.seekpos_audio = start * 1000;
    mp->mp_seek_base = r.seekpos_video;
    mp->mp_video.mq_seektarget = r.seekpos_video;
    mp->mp_audio.mq_seektarget = r.seekpos_video;
  } else {
    mp->mp_video.mq_seektarget = AV_NOPTS_VALUE;
    mp->mp_audio.mq_seektarget = AV_NOPTS_VALUE;
    mp->mp_seek_base = 0;
    r.seekpos_audio = AV_NOPTS_VALUE;
    r.seekpos_video = AV_NOPTS_VALUE;
  }

  mp_configure(mp, MP_PLAY_CAPS_PAUSE, MP_BUFFER_DEEP, 0);
  mp->mp_max_realtime_delay = (r.r->Link.timeout - 1) * 1000000;

  mp_become_primary(mp);

  metadb_register_play(va.canonical_url, 0, CONTENT_VIDEO);

  r.canonical_url = va.canonical_url;
  r.restartpos_last = -1;

  sub_scanner_t *ss =
    sub_scanner_create(url, mp->mp_prop_subtitle_tracks, &va, 0);

  e = rtmp_loop(&r, mp, url, errbuf, errlen);

  sub_scanner_destroy(ss);

  if(r.total_duration) {
    int p = mp->mp_seek_base / (r.total_duration * 10);
    if(p >= video_settings.played_threshold) {
      TRACE(TRACE_DEBUG, "RTMP", "Playback reached %d%%, counting as played",
	    p);
      metadb_register_play(va.canonical_url, 1, CONTENT_VIDEO);
      metadb_set_video_restartpos(va.canonical_url, -1);
    }
  }

  mp_flush(mp, 0);
  mp_shutdown(mp);

  TRACE(TRACE_DEBUG, "RTMP", "End of stream");

  rtmp_free(&r);
  return e;
}
Exemple #22
0
void doServe(STREAMING_SERVER * server,	// server socket and state (our listening socket)
	int sockfd	// client connection socket
	)
{
	server->state = STREAMING_IN_PROGRESS;

	RTMP *rtmp = RTMP_Alloc();		/* our session with the real client */
	RTMPPacket packet = { 0 };

	// timeout for http requests
	fd_set fds;
	struct timeval tv;

	memset(&tv, 0, sizeof(struct timeval));
	tv.tv_sec = 5;

	FD_ZERO(&fds);
	FD_SET(sockfd, &fds);

	if (select(sockfd + 1, &fds, NULL, NULL, &tv) <= 0)
	{
		RTMP_Log(RTMP_LOGERROR, "Request timeout/select failed, ignoring request");
		goto quit;
	}
	else
	{
		RTMP_Init(rtmp);
		rtmp->m_sb.sb_socket = sockfd;
		if (sslCtx && !RTMP_TLS_Accept(rtmp, sslCtx))
		{
			RTMP_Log(RTMP_LOGERROR, "TLS handshake failed");
			goto cleanup;
		}
		if (!RTMP_Serve(rtmp))
		{
			RTMP_Log(RTMP_LOGERROR, "Handshake failed");
			goto cleanup;
		}
	}
	server->arglen = 0;
	while (RTMP_IsConnected(rtmp) && RTMP_ReadPacket(rtmp, &packet))
	{
		if (!RTMPPacket_IsReady(&packet))
			continue;
		ServePacket(server, rtmp, &packet);
		RTMPPacket_Free(&packet);
	}

cleanup:
	RTMP_LogPrintf("Closing connection... ");
	RTMP_Close(rtmp);
	/* Should probably be done by RTMP_Close() ... */
	rtmp->Link.playpath.av_val = NULL;
	rtmp->Link.tcUrl.av_val = NULL;
	rtmp->Link.swfUrl.av_val = NULL;
	rtmp->Link.pageUrl.av_val = NULL;
	rtmp->Link.app.av_val = NULL;
	rtmp->Link.flashVer.av_val = NULL;
	if (rtmp->Link.usherToken.av_val)
	{
		free(rtmp->Link.usherToken.av_val);
		rtmp->Link.usherToken.av_val = NULL;
	}
	RTMP_Free(rtmp);
	RTMP_LogPrintf("done!\n\n");

quit:
	if (server->state == STREAMING_IN_PROGRESS)
		server->state = STREAMING_ACCEPTING;

	return;
}