コード例 #1
0
 function DownloadFragments($cc, $manifest, $opt = array())
 {
     $start = 0;
     extract($opt, EXTR_IF_EXISTS);
     $this->ParseManifest($cc, $manifest);
     $segNum = $this->segStart;
     $fragNum = $this->fragStart;
     if ($start) {
         $segNum = $this->GetSegmentFromFragment($start);
         $fragNum = $start - 1;
         $this->segStart = $segNum;
         $this->fragStart = $fragNum;
     }
     $this->lastFrag = $fragNum;
     $opt['cc'] = $cc;
     $opt['duration'] = 0;
     $firstFragment = reset($this->fragTable);
     LogInfo(sprintf("Fragments Total: %s, First: %s, Start: %s, Parallel: %s", $this->fragCount, $firstFragment['firstFragment'], $fragNum + 1, $this->parallel));
     // Extract baseFilename
     $this->baseFilename = $this->media['url'];
     if (substr($this->baseFilename, -1) == '/') {
         $this->baseFilename = substr($this->baseFilename, 0, -1);
     }
     $this->baseFilename = RemoveExtension($this->baseFilename);
     $lastSlash = strrpos($this->baseFilename, '/');
     if ($lastSlash !== false) {
         $this->baseFilename = substr($this->baseFilename, $lastSlash + 1);
     }
     if (strpos($manifest, '?')) {
         $this->baseFilename = md5(substr($manifest, 0, strpos($manifest, '?'))) . '_' . $this->baseFilename;
     } else {
         $this->baseFilename = md5($manifest) . '_' . $this->baseFilename;
     }
     $this->baseFilename .= "Seg" . $segNum . "-Frag";
     if ($fragNum >= $this->fragCount) {
         LogError("No fragment available for downloading");
     }
     $this->fragUrl = AbsoluteUrl($this->baseUrl, $this->media['url']);
     LogDebug("Base Fragment Url:\n" . $this->fragUrl . "\n");
     LogDebug("Downloading Fragments:\n");
     while ($fragNum < $this->fragCount or $cc->active) {
         while (count($cc->ch) < $this->parallel and $fragNum < $this->fragCount) {
             $frag = array();
             $fragNum = $fragNum + 1;
             $frag['id'] = $fragNum;
             LogInfo("Downloading {$fragNum}/{$this->fragCount} fragments", true);
             if (in_array_field($fragNum, "firstFragment", $this->fragTable, true)) {
                 $this->discontinuity = value_in_array_field($fragNum, "firstFragment", "discontinuityIndicator", $this->fragTable, true);
             } else {
                 $closest = reset($this->fragTable);
                 $closest = $closest['firstFragment'];
                 while ($current = next($this->fragTable)) {
                     if ($current['firstFragment'] < $fragNum) {
                         $closest = $current['firstFragment'];
                     } else {
                         break;
                     }
                 }
                 $this->discontinuity = value_in_array_field($closest, "firstFragment", "discontinuityIndicator", $this->fragTable, true);
             }
             if ($this->discontinuity !== "") {
                 LogDebug("Skipping fragment {$fragNum} due to discontinuity, Type: " . $this->discontinuity);
                 $frag['response'] = false;
                 $this->rename = true;
             } else {
                 if (file_exists($this->baseFilename . $fragNum)) {
                     LogDebug("Fragment {$fragNum} is already downloaded");
                     $frag['response'] = file_get_contents($this->baseFilename . $fragNum);
                 }
             }
             if (isset($frag['response'])) {
                 if ($this->WriteFragment($frag, $opt) === STOP_PROCESSING) {
                     break 2;
                 } else {
                     continue;
                 }
             }
             LogDebug("Adding fragment {$fragNum} to download queue");
             $segNum = $this->GetSegmentFromFragment($fragNum);
             $cc->addDownload($this->fragUrl . "Seg" . $segNum . "-Frag" . $fragNum . $this->media['queryString'], $fragNum);
         }
         $downloads = $cc->checkDownloads();
         if ($downloads !== false) {
             for ($i = 0; $i < count($downloads); $i++) {
                 $frag = array();
                 $download = $downloads[$i];
                 $frag['id'] = $download['id'];
                 if ($download['status'] == 200) {
                     if ($this->VerifyFragment($download['response'])) {
                         LogDebug("Fragment " . $this->baseFilename . $download['id'] . " successfully downloaded");
                         if (!($this->live or $this->play)) {
                             file_put_contents($this->baseFilename . $download['id'], $download['response']);
                         }
                         $frag['response'] = $download['response'];
                     } else {
                         LogDebug("Fragment " . $download['id'] . " failed to verify");
                         LogDebug("Adding fragment " . $download['id'] . " to download queue");
                         $cc->addDownload($download['url'], $download['id']);
                     }
                 } else {
                     if ($download['status'] === false) {
                         LogDebug("Fragment " . $download['id'] . " failed to download");
                         LogDebug("Adding fragment " . $download['id'] . " to download queue");
                         $cc->addDownload($download['url'], $download['id']);
                     } else {
                         if ($download['status'] == 403) {
                             LogError("Access Denied! Unable to download fragments.");
                         } else {
                             if ($download['status'] == 503) {
                                 LogDebug("Fragment " . $download['id'] . " seems temporary unavailable");
                                 LogDebug("Adding fragment " . $download['id'] . " to download queue");
                                 $cc->addDownload($download['url'], $download['id']);
                             } else {
                                 LogDebug("Fragment " . $download['id'] . " doesn't exist, Status: " . $download['status']);
                                 $frag['response'] = false;
                                 $this->rename = true;
                                 /* Resync with latest available fragment when we are left behind due to slow *
                                  * connection and short live window on streaming server. make sure to reset  *
                                  * the last written fragment.                                                */
                                 if ($this->live and $fragNum >= $this->fragCount and $i + 1 == count($downloads) and !$cc->active) {
                                     LogDebug("Trying to resync with latest available fragment");
                                     if ($this->WriteFragment($frag, $opt) === STOP_PROCESSING) {
                                         break 2;
                                     }
                                     unset($frag['response']);
                                     $this->UpdateBootstrapInfo($cc, $this->bootstrapUrl);
                                     $fragNum = $this->fragCount - 1;
                                     $this->lastFrag = $fragNum;
                                 }
                             }
                         }
                     }
                 }
                 if (isset($frag['response'])) {
                     if ($this->WriteFragment($frag, $opt) === STOP_PROCESSING) {
                         break 2;
                     }
                 }
             }
             unset($downloads, $download);
         }
         if ($this->live and $fragNum >= $this->fragCount and !$cc->active) {
             $this->UpdateBootstrapInfo($cc, $this->bootstrapUrl);
         }
     }
     LogInfo("");
     LogDebug("\nAll fragments downloaded successfully\n");
     $cc->stopDownloads();
     $this->processed = true;
 }
コード例 #2
0
 function DownloadFragments($cc, $manifest, $opt = array())
 {
     $start = 0;
     extract($opt, EXTR_IF_EXISTS);
     $this->ParseManifest($cc, $manifest);
     $segNum = $this->segStart;
     $fragNum = $this->fragStart;
     if ($start) {
         if ($segNum > 1) {
             if ($start % $this->fragsPerSeg) {
                 $segNum = (int) ($start / $this->fragsPerSeg + 1);
             } else {
                 $segNum = (int) ($start / $this->fragsPerSeg);
             }
         }
         $fragNum = $start - 1;
         $this->segStart = $segNum;
         $this->fragStart = $fragNum;
     }
     $this->lastFrag = $fragNum;
     $opt['cc'] = $cc;
     $opt['duration'] = 0;
     // Extract baseFilename
     $this->baseFilename = $this->media['url'];
     if (substr($this->baseFilename, -1) == '/') {
         $this->baseFilename = substr($this->baseFilename, 0, -1);
     }
     $this->baseFilename = RemoveExtension($this->baseFilename);
     if (strrpos($this->baseFilename, '/')) {
         $this->baseFilename = substr($this->baseFilename, strrpos($this->baseFilename, '/') + 1);
     }
     if (strpos($manifest, "?")) {
         $this->baseFilename = md5(substr($manifest, 0, strpos($manifest, "?"))) . "_" . $this->baseFilename;
     } else {
         $this->baseFilename = md5($manifest) . "_" . $this->baseFilename;
     }
     $this->baseFilename .= "Seg" . $segNum . "-Frag";
     if ($fragNum >= $this->fragCount) {
         LogError("No fragment available for downloading");
     }
     if (isHttpUrl($this->media['url'])) {
         $this->fragUrl = $this->media['url'];
     } else {
         $this->fragUrl = $this->baseUrl . "/" . $this->media['url'];
     }
     $this->fragUrl = NormalizePath($this->fragUrl);
     LogDebug("Base Fragment Url:\n" . $this->fragUrl . "\n");
     LogDebug("Downloading Fragments:\n");
     while ($fragNum < $this->fragCount or $cc->active) {
         while (count($cc->ch) < $this->parallel and $fragNum < $this->fragCount) {
             $frag = array();
             $fragNum = $fragNum + 1;
             $frag['id'] = $fragNum;
             LogInfo("Downloading {$fragNum}/{$this->fragCount} fragments", true);
             if (in_array_field($fragNum, "firstFragment", $this->fragTable, true)) {
                 $this->discontinuity = value_in_array_field($fragNum, "firstFragment", "discontinuityIndicator", $this->fragTable, true);
             } else {
                 $closest = 1;
                 foreach ($this->fragTable as $item) {
                     if ($item['firstFragment'] < $fragNum) {
                         $closest = $item['firstFragment'];
                     } else {
                         break;
                     }
                 }
                 $this->discontinuity = value_in_array_field($closest, "firstFragment", "discontinuityIndicator", $this->fragTable, true);
             }
             if ($this->discontinuity == 1 or $this->discontinuity == 3) {
                 LogDebug("Skipping fragment {$fragNum} due to discontinuity");
                 $frag['response'] = false;
                 $this->rename = true;
             } else {
                 if (file_exists($this->baseFilename . $fragNum)) {
                     LogDebug("Fragment {$fragNum} is already downloaded");
                     $frag['response'] = file_get_contents($this->baseFilename . $fragNum);
                 }
             }
             if (isset($frag['response'])) {
                 if ($this->WriteFragment($frag, $opt) === 2) {
                     break 2;
                 } else {
                     continue;
                 }
             }
             /* Increase or decrease segment number if current fragment is not available */
             /* in selected segment range                                                */
             if (count($this->segTable) > 1) {
                 if ($fragNum > $segNum * $this->fragsPerSeg) {
                     $segNum++;
                 } else {
                     if ($fragNum <= ($segNum - 1) * $this->fragsPerSeg) {
                         $segNum--;
                     }
                 }
             }
             LogDebug("Adding fragment {$fragNum} to download queue");
             $cc->addDownload($this->fragUrl . "Seg" . $segNum . "-Frag" . $fragNum . $this->auth, $fragNum);
         }
         $downloads = $cc->checkDownloads();
         if ($downloads !== false) {
             for ($i = 0; $i < count($downloads); $i++) {
                 $frag = array();
                 $download = $downloads[$i];
                 $frag['id'] = $download['id'];
                 if ($download['status'] == 200) {
                     if ($this->VerifyFragment($download['response'])) {
                         LogDebug("Fragment " . $this->baseFilename . $download['id'] . " successfully downloaded");
                         if (!($this->live or $this->play)) {
                             file_put_contents($this->baseFilename . $download['id'], $download['response']);
                         }
                         $frag['response'] = $download['response'];
                     } else {
                         LogDebug("Fragment " . $download['id'] . " failed to verify");
                         LogDebug("Adding fragment " . $download['id'] . " to download queue");
                         $cc->addDownload($download['url'], $download['id']);
                     }
                 } else {
                     if ($download['status'] === false) {
                         LogDebug("Fragment " . $download['id'] . " failed to download");
                         LogDebug("Adding fragment " . $download['id'] . " to download queue");
                         $cc->addDownload($download['url'], $download['id']);
                     } else {
                         if ($download['status'] == 403) {
                             LogError("Access Denied! Unable to download fragments.");
                         } else {
                             LogDebug("Fragment " . $download['id'] . " doesn't exist, Status: " . $download['status']);
                             $frag['response'] = false;
                             $this->rename = true;
                             /* Resync with latest available fragment when we are left behind due to */
                             /* slow connection and short live window on streaming server. make sure */
                             /* to reset the last written fragment.                                  */
                             if ($this->live and $i + 1 == count($downloads) and !$cc->active) {
                                 LogDebug("Trying to resync with latest available fragment");
                                 if ($this->WriteFragment($frag, $opt) === 2) {
                                     break 2;
                                 }
                                 unset($frag['response']);
                                 $this->UpdateBootstrapInfo($cc, $this->bootstrapUrl);
                                 $fragNum = $this->fragCount - 1;
                                 $this->lastFrag = $fragNum;
                             }
                         }
                     }
                 }
                 if (isset($frag['response'])) {
                     if ($this->WriteFragment($frag, $opt) === 2) {
                         break 2;
                     }
                 }
             }
             unset($downloads, $download);
         }
         if ($this->live and $fragNum >= $this->fragCount and !$cc->active) {
             $this->UpdateBootstrapInfo($cc, $this->bootstrapUrl);
         }
     }
     LogInfo("");
     LogDebug("\nAll fragments downloaded successfully\n");
     $cc->stopDownloads();
     $this->processed = true;
 }