unsigned int CFileShoutcast::Read(void* lpBuf, __int64 uiBufSize) { if (m_fileState.bRipDone) { OutputDebugString("Read done\n"); return 0; } while (m_ringbuf.GetMaxReadSize() <= 0) Sleep(10); int iRead = m_ringbuf.GetMaxReadSize(); if (iRead > uiBufSize) iRead = (int)uiBufSize; m_ringbuf.ReadBinary((char*)lpBuf, iRead); if (timeGetTime() - m_dwLastTime > 500) { m_dwLastTime = timeGetTime(); CMusicInfoTag tag; GetMusicInfoTag(tag); g_infoManager.SetCurrentSongTag(tag); } return iRead; }
bool CFileShoutcast::Open(const CURL& url, bool bBinary) { m_dwLastTime = timeGetTime(); int ret; CGUIDialogProgress* dlgProgress = (CGUIDialogProgress*)m_gWindowManager.GetWindow(WINDOW_DIALOG_PROGRESS); set_rip_manager_options_defaults(&m_opt); strcpy(m_opt.output_directory, "./"); m_opt.proxyurl[0] = '\0'; // Use a proxy, if the GUI was configured as such bool bProxyEnabled = g_guiSettings.GetBool("network.usehttpproxy"); if (bProxyEnabled) { const CStdString &strProxyServer = g_guiSettings.GetString("network.httpproxyserver"); const CStdString &strProxyPort = g_guiSettings.GetString("network.httpproxyport"); // Should we check for valid strings here #ifndef _LINUX _snprintf( m_opt.proxyurl, MAX_URL_LEN, "http://%s:%s", strProxyServer.c_str(), strProxyPort.c_str() ); #else snprintf( m_opt.proxyurl, MAX_URL_LEN, "http://%s:%s", strProxyServer.c_str(), strProxyPort.c_str() ); #endif } CStdString strUrl; url.GetURL(strUrl); strUrl.Replace("shout://", "http://"); printf("Opening url: %s\n", strUrl.c_str()); strncpy(m_opt.url, strUrl.c_str(), MAX_URL_LEN); sprintf(m_opt.useragent, "x%s", url.GetFileName().c_str()); if (dlgProgress) { dlgProgress->SetHeading(260); dlgProgress->SetLine(0, 259); dlgProgress->SetLine(1, strUrl); dlgProgress->SetLine(2, ""); if (!dlgProgress->IsDialogRunning()) dlgProgress->StartModal(); dlgProgress->Progress(); } if ((ret = rip_manager_start(rip_callback, &m_opt)) != SR_SUCCESS) { if (dlgProgress) dlgProgress->Close(); return false; } int iShoutcastTimeout = 10 * SHOUTCASTTIMEOUT; //i.e: 10 * 10 = 100 * 100ms = 10s int iCount = 0; while (!m_fileState.bRipDone && !m_fileState.bRipStarted && !m_fileState.bRipError && (!dlgProgress || !dlgProgress->IsCanceled())) { if (iCount <= iShoutcastTimeout) //Normally, this isn't the problem, //because if RIP_MANAGER fails, this would be here //with m_fileState.bRipError { Sleep(100); } else { if (dlgProgress) { dlgProgress->SetLine(1, 257); dlgProgress->SetLine(2, "Connection timed out..."); Sleep(1500); dlgProgress->Close(); } return false; } iCount++; } if (dlgProgress && dlgProgress->IsCanceled()) { Close(); dlgProgress->Close(); return false; } /* store content type of stream */ m_contenttype = rip_manager_get_content_type(); //CHANGED CODE: Don't reset timer anymore. while (!m_fileState.bRipDone && !m_fileState.bRipError && m_fileState.bBuffering && (!dlgProgress || !dlgProgress->IsCanceled())) { if (iCount <= iShoutcastTimeout) //Here is the real problem: Sometimes the buffer fills just to //slowly, thus the quality of the stream will be bad, and should be //aborted... { Sleep(100); char szTmp[1024]; //g_dialog.SetCaption(0, "Shoutcast" ); sprintf(szTmp, "Buffering %i bytes", m_ringbuf.GetMaxReadSize()); if (dlgProgress) { dlgProgress->SetLine(2, szTmp ); dlgProgress->Progress(); } sprintf(szTmp, "%s", m_ripInfo.filename); for (int i = 0; i < (int)strlen(szTmp); i++) szTmp[i] = tolower((unsigned char)szTmp[i]); szTmp[50] = 0; if (dlgProgress) { dlgProgress->SetLine(1, szTmp ); dlgProgress->Progress(); } } else //it's not really a connection timeout, but it's here, //where things get boring, if connection is slow. //trust me, i did a lot of testing... Doesn't happen often, //but if it does it sucks to wait here forever. //CHANGED: Other message here { if (dlgProgress) { dlgProgress->SetLine(1, 257); dlgProgress->SetLine(2, "Connection to server too slow..."); dlgProgress->Close(); } return false; } iCount++; } if (dlgProgress && dlgProgress->IsCanceled()) { Close(); dlgProgress->Close(); return false; } if ( m_fileState.bRipError ) { if (dlgProgress) { dlgProgress->SetLine(1, 257); dlgProgress->SetLine(2, m_errorInfo.error_str); dlgProgress->Progress(); Sleep(1500); dlgProgress->Close(); } return false; } if (dlgProgress) { dlgProgress->SetLine(2, 261); dlgProgress->Progress(); dlgProgress->Close(); } return true; }