示例#1
0
bool CUPnPPlayer::QueueNextFile(const CFileItem& file)
{
  CFileItem item(file);
  NPT_Reference<CThumbLoader> thumb_loader;
  NPT_Reference<PLT_MediaObject> obj;
  NPT_String path(file.GetPath().c_str());
  NPT_String tmp;

  if (file.IsVideoDb())
    thumb_loader = NPT_Reference<CThumbLoader>(new CVideoThumbLoader());
  else if (item.IsMusicDb())
    thumb_loader = NPT_Reference<CThumbLoader>(new CMusicThumbLoader());


  obj = BuildObject(item, path, 0, thumb_loader, NULL, CUPnP::GetServer(), UPnPPlayer);
  if(!obj.IsNull())
  {
    NPT_CHECK_LABEL_SEVERE(PLT_Didl::ToDidl(*obj, "", tmp), failed);
    tmp.Insert(didl_header, 0);
    tmp.Append(didl_footer);
  }

  NPT_CHECK_LABEL_WARNING(m_control->SetNextAVTransportURI(m_delegate->m_device
                                                         , m_delegate->m_instance
                                                         , file.GetPath().c_str()
                                                         , (const char*)tmp
                                                         , m_delegate), failed);
  if(!m_delegate->m_resevent.WaitMSec(10000)) goto failed;
  NPT_CHECK_LABEL_WARNING(m_delegate->m_resstatus, failed);
  return true;

failed:
  CLog::Log(LOGERROR, "UPNP: CUPnPPlayer::QueueNextFile - unable to queue file %s", file.GetPath().c_str());
  return false;
}
示例#2
0
/*----------------------------------------------------------------------
|   main
+---------------------------------------------------------------------*/
int
main(int argc, char** argv)
{
    NPT_COMPILER_UNUSED(argc);

    NPT_HttpRequestHandler *handler, *custom_handler;
    NPT_Reference<NPT_DataBuffer> buffer;
    NPT_Size size;
    bool result;
    PLT_RingBufferStreamReference ringbuffer_stream(new PLT_RingBufferStream());

    /* parse command line */
    ParseCommandLine(argv);

    /* create http server */
    PLT_HttpServer http_server(Options.port?Options.port:80);
    NPT_String url = "http://127.0.0.1:" + NPT_String::FromInteger(http_server.GetPort());
    NPT_String custom_url = url;

    if (!Options.path.IsEmpty()) {
        /* extract folder path */
        int index1 = Options.path.ReverseFind('\\');
        int index2 = Options.path.ReverseFind('/');
        if (index1 <= 0 && index2 <=0) {
            fprintf(stderr, "ERROR: invalid path\n");
            exit(1);
        }

        NPT_DirectoryEntryInfo info;
        NPT_CHECK_SEVERE(NPT_DirectoryEntry::GetInfo(Options.path, &info));

        /* add file request handler */
        handler = new NPT_HttpFileRequestHandler(
            Options.path.Left(index1>index2?index1:index2), 
            "/");
        http_server.AddRequestHandler(handler, "/", true);

        /* build url*/
        url += "/" + Options.path.SubString((index1>index2?index1:index2)+1);
    } else {
        /* create random data */
        buffer = new NPT_DataBuffer(32768);
        buffer->SetDataSize(32768);

        /* add static handler */
        handler = new NPT_HttpStaticRequestHandler(buffer->GetData(),
            buffer->GetDataSize(),
            "text/xml");
        http_server.AddRequestHandler(handler, "/test");

        /* build url*/
        url += "/test";
    }

    /* add custom handler */
    NPT_InputStreamReference stream(ringbuffer_stream);
    custom_handler = new PLT_HttpCustomRequestHandler(stream,
        "text/xml");
    http_server.AddRequestHandler(custom_handler, "/custom");
    custom_url += "/custom";

    /* start server */
    NPT_CHECK_SEVERE(http_server.Start());

    /* a task manager for the tests downloader */
    PLT_TaskManager task_manager;

    /* small delay to let the server start */
    NPT_System::Sleep(NPT_TimeInterval(1, 0));
    
    /* execute tests */
    result = Test1(&task_manager, url.GetChars(), size);
    if (!result) return -1;

    result = Test2(&task_manager, url.GetChars(), size);
    if (!result) return -1;

    result = Test3(&task_manager, custom_url.GetChars(), ringbuffer_stream, size);
    if (!result) return -1;

    NPT_System::Sleep(NPT_TimeInterval(1, 0));

    http_server.Stop();
    delete handler;
    delete custom_handler;
    return 0;
}
示例#3
0
bool CUPnPPlayer::OpenFile(const CFileItem& file, const CPlayerOptions& options)
{
  CFileItem item(file);
  NPT_Reference<CThumbLoader> thumb_loader;
  NPT_Reference<PLT_MediaObject> obj;
  NPT_String path(file.GetPath().c_str());
  NPT_String tmp, resource;
  XbmcThreads::EndTime timeout;
  CGUIDialogBusy* dialog = NULL;

  NPT_CHECK_POINTER_LABEL_SEVERE(m_delegate, failed);

  timeout.Set(10000);

  /* if no path we want to attach to a already playing player */
  if(path != "") {
    if (file.IsVideoDb())
      thumb_loader = NPT_Reference<CThumbLoader>(new CVideoThumbLoader());
    else if (item.IsMusicDb())
      thumb_loader = NPT_Reference<CThumbLoader>(new CMusicThumbLoader());

    obj = BuildObject(item, path, false, thumb_loader, NULL, CUPnP::GetServer());
    if(obj.IsNull()) goto failed;

    NPT_CHECK_LABEL_SEVERE(PLT_Didl::ToDidl(*obj, "", tmp), failed);
    tmp.Insert(didl_header, 0);
    tmp.Append(didl_footer);

    /* The resource uri's are stored in the Didl. We must choose the best resource
     * for the playback device */
    NPT_Cardinal res_index;
    NPT_CHECK_LABEL_SEVERE(m_control->FindBestResource(m_delegate->m_device, *obj, res_index), failed);


    /* dlna specifies that a return code of 705 should be returned
     * if TRANSPORT_STATE is not STOPPED or NO_MEDIA_PRESENT */
    NPT_CHECK_LABEL_SEVERE(m_control->Stop(m_delegate->m_device
                                           , m_delegate->m_instance
                                           , m_delegate), failed);
    NPT_CHECK_LABEL_SEVERE(WaitOnEvent(m_delegate->m_resevent, timeout, dialog), failed);
    NPT_CHECK_LABEL_SEVERE(m_delegate->m_resstatus, failed);


    NPT_CHECK_LABEL_SEVERE(m_control->SetAVTransportURI(m_delegate->m_device
                                                      , m_delegate->m_instance
                                                      , obj->m_Resources[res_index].m_Uri
                                                      , (const char*)tmp
                                                      , m_delegate), failed);
    NPT_CHECK_LABEL_SEVERE(WaitOnEvent(m_delegate->m_resevent, timeout, dialog), failed);
    NPT_CHECK_LABEL_SEVERE(m_delegate->m_resstatus, failed);

    NPT_CHECK_LABEL_SEVERE(m_control->Play(m_delegate->m_device
                                         , m_delegate->m_instance
                                         , "1"
                                         , m_delegate), failed);
    NPT_CHECK_LABEL_SEVERE(WaitOnEvent(m_delegate->m_resevent, timeout, dialog), failed);
    NPT_CHECK_LABEL_SEVERE(m_delegate->m_resstatus, failed);
  }


  /* wait for PLAYING state */
  do {
    NPT_CHECK_LABEL_SEVERE(m_control->GetTransportInfo(m_delegate->m_device
                                                     , m_delegate->m_instance
                                                     , m_delegate), failed);


    { CSingleLock lock(m_delegate->m_section);
      if(m_delegate->m_trainfo.cur_transport_state == "PLAYING"
      || m_delegate->m_trainfo.cur_transport_state == "PAUSED_PLAYBACK")
        break;

      if(m_delegate->m_trainfo.cur_transport_state  == "STOPPED"
      && m_delegate->m_trainfo.cur_transport_status != "OK")
      {
        CLog::Log(LOGERROR, "UPNP: CUPnPPlayer::OpenFile - remote player signalled error %s", file.GetPath().c_str());
        goto failed;
      }
    }

    NPT_CHECK_LABEL_SEVERE(WaitOnEvent(m_delegate->m_traevnt, timeout, dialog), failed);

  } while(!timeout.IsTimePast());

  if(options.starttime > 0)
  {
    /* many upnp units won't load file properly until after play (including xbmc) */
    NPT_CHECK_LABEL(m_control->Seek(m_delegate->m_device
                                    , m_delegate->m_instance
                                    , "REL_TIME"
                                    , PLT_Didl::FormatTimeStamp((NPT_UInt32)options.starttime)
                                    , m_delegate), failed);
  }

  m_started = true;
  m_callback.OnPlayBackStarted();
  NPT_CHECK_LABEL_SEVERE(m_control->GetPositionInfo(m_delegate->m_device
                                                  , m_delegate->m_instance
                                                  , m_delegate), failed);
  NPT_CHECK_LABEL_SEVERE(m_control->GetMediaInfo(m_delegate->m_device
                                               , m_delegate->m_instance
                                               , m_delegate), failed);

  if(dialog)
    dialog->Close();

  return true;
failed:
  CLog::Log(LOGERROR, "UPNP: CUPnPPlayer::OpenFile - unable to open file %s", file.GetPath().c_str());
  if(dialog)
    dialog->Close();
  return false;
}
示例#4
0
int CUPnPPlayer::PlayFile(const CFileItem& file, const CPlayerOptions& options, CGUIDialogBusy*& dialog, XbmcThreads::EndTime& timeout)
{
  CFileItem item(file);
  NPT_Reference<CThumbLoader> thumb_loader;
  NPT_Reference<PLT_MediaObject> obj;
  NPT_String path(file.GetPath().c_str());
  NPT_String tmp, resource;
  EMediaControllerQuirks quirks = EMEDIACONTROLLERQUIRKS_NONE;

  NPT_CHECK_POINTER_LABEL_SEVERE(m_delegate, failed);

  if (file.IsVideoDb())
    thumb_loader = NPT_Reference<CThumbLoader>(new CVideoThumbLoader());
  else if (item.IsMusicDb())
    thumb_loader = NPT_Reference<CThumbLoader>(new CMusicThumbLoader());

  obj = BuildObject(item, path, false, thumb_loader, NULL, CUPnP::GetServer(), UPnPPlayer);
  if(obj.IsNull()) goto failed;

  NPT_CHECK_LABEL_SEVERE(PLT_Didl::ToDidl(*obj, "", tmp), failed_todidl);
  tmp.Insert(didl_header, 0);
  tmp.Append(didl_footer);

  quirks = GetMediaControllerQuirks(m_delegate->m_device.AsPointer());
  if (quirks & EMEDIACONTROLLERQUIRKS_X_MKV)
  {
    for (NPT_Cardinal i=0; i< obj->m_Resources.GetItemCount(); i++) {
      if (obj->m_Resources[i].m_ProtocolInfo.GetContentType().Compare("video/x-matroska") == 0) {
        CLog::Log(LOGDEBUG, "CUPnPPlayer::PlayFile(%s): applying video/x-mkv quirk", file.GetPath().c_str());
        NPT_String protocolInfo = obj->m_Resources[i].m_ProtocolInfo.ToString();
        protocolInfo.Replace(":video/x-matroska:", ":video/x-mkv:");
        obj->m_Resources[i].m_ProtocolInfo = PLT_ProtocolInfo(protocolInfo);
      }
    }
  }

  /* The resource uri's are stored in the Didl. We must choose the best resource
   * for the playback device */
  NPT_Cardinal res_index;
  NPT_CHECK_LABEL_SEVERE(m_control->FindBestResource(m_delegate->m_device, *obj, res_index), failed_findbestresource);

  // get the transport info to evaluate the TransportState to be able to
  // determine whether we first need to call Stop()
  timeout.Set(timeout.GetInitialTimeoutValue());
  NPT_CHECK_LABEL_SEVERE(m_control->GetTransportInfo(m_delegate->m_device
                                                     , m_delegate->m_instance
                                                     , m_delegate), failed_gettransportinfo);
  NPT_CHECK_LABEL_SEVERE(WaitOnEvent(m_delegate->m_traevnt, timeout, dialog), failed_gettransportinfo);

  if (m_delegate->m_trainfo.cur_transport_state != "NO_MEDIA_PRESENT" &&
      m_delegate->m_trainfo.cur_transport_state != "STOPPED")
  {
    timeout.Set(timeout.GetInitialTimeoutValue());
    NPT_CHECK_LABEL_SEVERE(m_control->Stop(m_delegate->m_device
                                           , m_delegate->m_instance
                                           , m_delegate), failed_stop);
    NPT_CHECK_LABEL_SEVERE(WaitOnEvent(m_delegate->m_resevent, timeout, dialog), failed_stop);
    NPT_CHECK_LABEL_SEVERE(m_delegate->m_resstatus, failed_stop);
  }


  timeout.Set(timeout.GetInitialTimeoutValue());
  NPT_CHECK_LABEL_SEVERE(m_control->SetAVTransportURI(m_delegate->m_device
                                                    , m_delegate->m_instance
                                                    , obj->m_Resources[res_index].m_Uri
                                                    , (const char*)tmp
                                                    , m_delegate), failed_setavtransporturi);
  NPT_CHECK_LABEL_SEVERE(WaitOnEvent(m_delegate->m_resevent, timeout, dialog), failed_setavtransporturi);
  NPT_CHECK_LABEL_SEVERE(m_delegate->m_resstatus, failed_setavtransporturi);

  timeout.Set(timeout.GetInitialTimeoutValue());
  NPT_CHECK_LABEL_SEVERE(m_control->Play(m_delegate->m_device
                                       , m_delegate->m_instance
                                       , "1"
                                       , m_delegate), failed_play);
  NPT_CHECK_LABEL_SEVERE(WaitOnEvent(m_delegate->m_resevent, timeout, dialog), failed_play);
  NPT_CHECK_LABEL_SEVERE(m_delegate->m_resstatus, failed_play);


  /* wait for PLAYING state */
  timeout.Set(timeout.GetInitialTimeoutValue());
  do {
    NPT_CHECK_LABEL_SEVERE(m_control->GetTransportInfo(m_delegate->m_device
                                                     , m_delegate->m_instance
                                                     , m_delegate), failed_waitplaying);


    { CSingleLock lock(m_delegate->m_section);
      if(m_delegate->m_trainfo.cur_transport_state == "PLAYING"
      || m_delegate->m_trainfo.cur_transport_state == "PAUSED_PLAYBACK")
        break;

      if(m_delegate->m_trainfo.cur_transport_state  == "STOPPED"
      && m_delegate->m_trainfo.cur_transport_status != "OK")
      {
        CLog::Log(LOGERROR, "UPNP: CUPnPPlayer::OpenFile - remote player signalled error %s", file.GetPath().c_str());
        return NPT_FAILURE;
      }
    }

    NPT_CHECK_LABEL_SEVERE(WaitOnEvent(m_delegate->m_traevnt, timeout, dialog), failed_waitplaying);

  } while(!timeout.IsTimePast());

  if(options.starttime > 0)
  {
    /* many upnp units won't load file properly until after play (including xbmc) */
    NPT_CHECK_LABEL(m_control->Seek(m_delegate->m_device
                                    , m_delegate->m_instance
                                    , "REL_TIME"
                                    , PLT_Didl::FormatTimeStamp((NPT_UInt32)options.starttime)
                                    , m_delegate), failed_seek);
  }

  return NPT_SUCCESS;
failed_todidl:
  CLog::Log(LOGERROR, "CUPnPPlayer::PlayFile(%s) failed to serialize item into DIDL-Lite", file.GetPath().c_str());
  return NPT_FAILURE;
failed_findbestresource:
  CLog::Log(LOGERROR, "CUPnPPlayer::PlayFile(%s) failed to find a matching resource", file.GetPath().c_str());
  return NPT_FAILURE;
failed_gettransportinfo:
  CLog::Log(LOGERROR, "CUPnPPlayer::PlayFile(%s): call to GetTransportInfo failed", file.GetPath().c_str());
  return NPT_FAILURE;
failed_stop:
  CLog::Log(LOGERROR, "CUPnPPlayer::PlayFile(%s) failed to stop current playback", file.GetPath().c_str());
  return NPT_FAILURE;
failed_setavtransporturi:
  CLog::Log(LOGERROR, "CUPnPPlayer::PlayFile(%s) failed to set the playback URI", file.GetPath().c_str());
  return NPT_FAILURE;
failed_play:
  CLog::Log(LOGERROR, "CUPnPPlayer::PlayFile(%s) failed to start playback", file.GetPath().c_str());
  return NPT_FAILURE;
failed_waitplaying:
  CLog::Log(LOGERROR, "CUPnPPlayer::PlayFile(%s) failed to wait for PLAYING state", file.GetPath().c_str());
  return NPT_FAILURE;
failed_seek:
  CLog::Log(LOGERROR, "CUPnPPlayer::PlayFile(%s) failed to seek to start offset", file.GetPath().c_str());
  return NPT_FAILURE;
failed:
  CLog::Log(LOGERROR, "CUPnPPlayer::PlayFile(%s) failed", file.GetPath().c_str());
  return NPT_FAILURE;
}
示例#5
0
/*----------------------------------------------------------------------
|   main
+---------------------------------------------------------------------*/
int
main(int argc, char** argv)
{
    NPT_COMPILER_UNUSED(argc);
    
    NPT_HttpRequestHandler* handler;
    NPT_Reference<NPT_DataBuffer> buffer;
    bool result;

    /* parse command line */
    ParseCommandLine(argv);

    /* create http server */
    PLT_HttpServer http_server(Options.port?Options.port:8089);
    NPT_String url;

    if (!Options.path.IsEmpty()) {
        /* extract folder path */
        int index1 = Options.path.ReverseFind('\\');
        int index2 = Options.path.ReverseFind('/');
        if (index1 <= 0 && index2 <=0) {
            fprintf(stderr, "ERROR: invalid path\n");
            exit(1);
        }

        NPT_FileInfo info;
        NPT_CHECK_SEVERE(NPT_File::GetInfo(Options.path, &info));

        /* add file request handler */
        handler = new NPT_HttpFileRequestHandler(
            Options.path.Left(index1>index2?index1:index2), 
            "/");
        http_server.AddRequestHandler(handler, "/", true);

        /* build url */
        url = "/" + Options.path.SubString((index1>index2?index1:index2)+1);
    } else {
        /* create random garbage data */
        buffer = new NPT_DataBuffer(32768);
        buffer->SetDataSize(32768);

        /* add static handler */
        handler = new NPT_HttpStaticRequestHandler(buffer->GetData(),
            buffer->GetDataSize(),
            "application/octet-stream");
        http_server.AddRequestHandler(handler, "/test");

        /* build url */
        url = "/test";
    }

    /* add custom handler */
    PLT_RingBufferStreamReference ringbuffer_stream(new PLT_RingBufferStream());
    NPT_InputStreamReference stream(ringbuffer_stream);
    NPT_HttpRequestHandler* custom_handler = new PLT_HttpCustomRequestHandler(stream, "text/xml");
    http_server.AddRequestHandler(custom_handler, "/custom");
    
    /* start server */
    NPT_CHECK_SEVERE(http_server.Start());

    /* a task manager for the tests downloader */
    PLT_TaskManager task_manager;

    /* small delay to let the server start */
    NPT_System::Sleep(NPT_TimeInterval(1.f));
    
    /* execute tests */
    NPT_Size size;
    NPT_COMPILER_UNUSED(size);
    
#ifdef TEST1
    result = Test1(&task_manager, NPT_HttpUrl("127.0.0.1", http_server.GetPort(), url), size);
    if (!result) return -1;
#endif
    
#ifdef TEST2
    result = Test2(&task_manager, NPT_HttpUrl("127.0.0.1", http_server.GetPort(), url), size);
    if (!result) return -1;
#endif
    
#ifdef TEST3
    result = Test3(&task_manager, NPT_HttpUrl("127.0.0.1", http_server.GetPort(), "/custom"), ringbuffer_stream, size);
    if (!result) return -1;
#endif
    
#ifdef TEST4
    result = Test4(&task_manager, NPT_HttpUrl("127.0.0.1", http_server.GetPort(), "/custom"), NPT_TimeInterval(.1f));
    if (!result) return -1;
    
    result = Test4(&task_manager, NPT_HttpUrl("127.0.0.1", http_server.GetPort(), "/custom"), NPT_TimeInterval(1.f));
    if (!result) return -1;
    
    result = Test4(&task_manager, NPT_HttpUrl("127.0.0.1", http_server.GetPort(), "/custom"), NPT_TimeInterval(2.f));
    if (!result) return -1;
#endif
    
#ifdef TEST5
    result = Test5(NPT_HttpUrl("127.0.0.1", http_server.GetPort(), "/test"));
    if (!result) return -1;
#endif
    
    NPT_System::Sleep(NPT_TimeInterval(1.f));
    
    // abort server tasks that are waiting on ring buffer stream
    ringbuffer_stream->Abort();
    
    http_server.Stop();
    
    return 0;
}