aftamat4ik

Рейтинг
55
Регистрация
05.01.2012
Интересы
php + Drupal
программист недосамоучка
Asju:
Привет!!!
Все сделал как ты сказал. Список аудио файлов получаю, при попытки их воспроизвести результат нулевой, пишет что файл не существует. В чем причина?

В том что ВК АПИ - не позволяет получать аудио из своего VKAPI. Делай через curl и не парься) Я так сделал, все нормально пашет и списки получает и видео если надо будет тоже получу. PHP+CURL короче. только так.

Милованов Ю.С:
Да какая разница как? Хоть ПУТом, хоть ХЕДом - до фонаря. Проблема в том, что скрипт будет ждать результат курла, фопена или файл_гет_контентса.

curl_setopt($ch, CURLOPT_TIMEOUT_MS, 1);

Таки да хД

Но я это поборол хД

---------- Добавлено 28.02.2013 в 18:26 ----------

К стати сдеано примерно так:


$url = "test1.ru/rec.php";
if(isset($_GET['i'] <= $_GET["max"]){
sleep(20);
//..
//действия
//..
$i++;
$ch = curl_init($url."/?max=".$_GET['max']."&&i=".$i);//продолжаем рекурсию
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_exec ($ch);
curl_close ($ch);
}
if(!isset($_GET['max']) && !isset($_GET['i'])){//если икаких параметров не передано.
$max = 6;
$ch = curl_init($url."/?max=".$max."&&i=1");//запуск рекурсии
curl_setopt($ch, CURLOPT_TIMEOUT, 13);
curl_exec ($ch);
curl_close ($ch);
}


---------- Добавлено 28.02.2013 в 18:38 ----------

Теперь файл закачивается рекурсивно, все нормально. Но! Я хотел чтобы первые 500килобайт файла, как только пользователь их скачает - начинали бы скачиваться. В это время алгоритм подгрузит остальную часть файла, таким образом ускорится процесс... В общем пользователю будет проще, да и быстрее работать будет.

Не подскажите как это примерно реализовать? Копаю в сторону Chunked transfer encoding, мне именно это посоветовали здесь же на форуме. Но я если честно уже 2 день копаю в эту сторону и не могу заставить алгоритм работать так как мне надо. скачка начинается, но скачиваются только первые 500 килобит, остальное не передается. Что еще досаднее - урл у команды по которой мы получаем первый(начальный) пакет выглядит так: - test1.ru/rec.php, а урл с которого берется второй пакет так: test1.ru/rec.php/?max=6&&i=1 ну и так далее... Естесственно броузер не может собрать все воедино да и не возможно это. Есть мысли какие нибудь по этому поводу? Я уже всю свою фантазию израсходовал(

хм. В общем-то советы хорошие. но вся проблема в том что я использую рекурсию и файл нельзя скажем так сразу-же запихнуть в цикл и разобрать по частям(time-limit, именно из-за него и применена рекурсия) Вот код самой функции(это druplal 7)


<?php
$url = "http://test1.ru/somefile.php";//собсна путь к файлу(он на самом деле слегка не так получается у меня)

if(isset($_GET['file_url']) && $_GET['i'] != $_GET["iter"]){//если в файл переданы GET параметры
$file_url = $_GET['file_url'];
$file_name = $_GET['file_name'];
$i = $_GET['i'];

cl_Read($file_url,$file_name.".mp3",512000*$i,512000);//закачиваем файл
$i++;

$ch = curl_init($url."/?file_url=".$file_url."&&iter=".$_GET['iter']."&&i=".$i."&&file_name=".$file_name);//продолжаем рекурсию
curl_setopt($ch, CURLOPT_TIMEOUT, 1);//ожидание ответа сервера - 1 сек. Можно было CURLOPT_TIMEOUT_MS, однако не на всех хостингах последняя версия CURL стоит...
curl_exec ($ch);
curl_close ($ch);
}
if(!isset($_GET['file_url']) && !isset($_GET['i'])){

$file_url = "http://somesite/somefolder/file.mp3";//отсюда качаем

$file_name = './audio/1.mp3';//сюда сохраняем

$fsize = curl_get_file_size($file_url);//получаем размер файла(на удаленном сервере) в килобайтах
$iter = round($fsize/512000) + 1;//число итераций рекурсивного цикла до полной закачки файла частями по 500 килобайт +1 ибо округлению я не доверяю....

cl_Read($file_url,$file_name,0,512000);//первая часть трека. ее мы после загрузки начинаем проигрывать, чтобы пользователя не бесить...

echo $file_name;//передаем урл - ссылку на файл для начала проигрывания, эту ссылку мы получаем в javascript'e и дальше в плеер ее в плеер!

$ch = curl_init($url."/?file_url=".$file_url."&&iter=".$iter."&&i=1&&file_name=".$file_name);//запускаем рекурсию $i = 1, так как первая часть трека уже скачана
curl_setopt($ch, CURLOPT_TIMEOUT, 1);//минимальное ожидание ответа сервера
curl_exec ($ch);
curl_close ($ch);
}

exit();
?>



---------- Добавлено 26.02.2013 в 20:59 ----------

Тут хорошая функция закачки файла блоками - http://stackoverflow.com/questions/6914912/streaming-a-large-file-using-php

Которая тоже не канает из-за рекурсии(

Сам механизм Chunked transfer encoding мне не до конца ясен. Я пытался сделать так(по этому совету - http://stackoverflow.com/questions/13565952/transfer-encoding-chunked-header-in-php-what-is-padding-for):



$url = "http://test1.ru/somefile.php";//собсна путь к файлу(он на самом деле слегка не так получается у меня)

if(isset($_GET['file_url']) && $_GET['i'] != $_GET["iter"]){//если в файл переданы GET параметры
$file_url = $_GET['file_url'];
$file_name = $_GET['file_name'];
$i = $_GET['i'];

cl_Read($file_url,$file_name.".mp3",512000*$i,512000);//закачиваем файл
$i++;

$ch = curl_init($url."/?file_url=".$file_url."&&iter=".$_GET['iter']."&&i=".$i."&&file_name=".$file_name);//продолжаем рекурсию
curl_setopt($ch, CURLOPT_TIMEOUT, 1);//ожидание ответа сервера - 1 сек. Можно было CURLOPT_TIMEOUT_MS, однако не на всех хостингах последняя версия CURL стоит...
curl_exec ($ch);
curl_close ($ch);
}
if(!isset($_GET['file_url']) && !isset($_GET['i'])){

$file_url = "http://somesite/somefolder/file.mp3";//отсюда качаем

$file_name = './audio/1.mp3';//сюда сохраняем

$fsize = curl_get_file_size($file_url);//получаем размер файла(на удаленном сервере) в килобайтах
$iter = round($fsize/512000) + 1;//число итераций рекурсивного цикла до полной закачки файла частями по 500 килобайт +1 ибо округлению я не доверяю....

cl_Read($file_url,$file_name,0,512000);//первая часть трека. ее мы после загрузки начинаем проигрывать, чтобы пользователя не бесить...
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $name);
header('Content-Transfer-Encoding: binary');
header('Content-Encoding', 'chunked');
header('Transfer-Encoding', 'chunked');
header('Content-Type', 'audio/mpeg');
header('Connection', 'keep-alive');


//echo $file_name;//передаем урл - ссылку на файл для начала проигрывания, эту ссылку мы получаем в javascript'e и дальше в плеер ее в плеер!

$ch = curl_init($url."/?file_url=".$file_url."&&iter=".$iter."&&i=1&&file_name=".$file_name);//запускаем рекурсию $i = 1, так как первая часть трека уже скачана
curl_setopt($ch, CURLOPT_TIMEOUT, 1);//минимальное ожидание ответа сервера
curl_exec ($ch);
curl_close ($ch);
}

exit();
?>

После этого при переходе на урл http://test1.ru/somefile.php начиналось скачивание файла и хотя размер файла изменился минимум 2 раза к концу закачки, скачалось всего 500кб. Что я не так делаю то?

Ну не могу я файл разбить на части как здесь(ссылка откуда взят код - выше):


$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
$out = "GET / HTTP/1.1\r\n";
$out .= "Host: www.example.com\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}

while (!feof($fp)) {

echo fgets($fp, 128);

}

- не применимо! можно сделать так:

if(!eof($fp)) echo fgets($fp, 128);

но это не приводит к скачке полного файла

И опять-же сокеты мне что-то не по нраву.

В общем как объяснить броузеру что для скачивания следующей части файла надо перейти по такому-то адресу(по тому-же самому) и что передадут с этого адреса прибавить к тому что уже скачано.... ППЦ хД

---------- Добавлено 26.02.2013 в 15:26 ----------

siv1987:
Склеить части задача для школьника, но вопрос в другом, что мешает отдавать в трех "пакетах" по 500К в один файл?

Так так так, а по подробнее)

siv1987:
Что мешает отдавать пользователю непрерывно по 500К без всяких извращений?

и как потом пользователь это все во едино соберет?) допустим будет 3 скачки по 500 килобайт хД) Ну да так то я могу))

Представьте вы скачиваете с сайта 3 части одного! файла и пытаетесь их собрать хДД

Руками))

TF-Studio:
а не проще хостера сменить?
сейчас их как грязи.

Не, не, в хостере дело. Дело в модуле который пишу. Не все же пользователи имеют скажем так безграничные ресурсы на своих хостингах и прочем => значит надо максимально оптимизировать код под среднестатического юзеря, который не хочет портить себе нервы общением с хостером, а хочет просто Результат.

В итоге приходится оптимизировать код под стандартизированный конфиг сервера...

ivan-lev:
Эм.. а точно time_limit не нравится хостингу?

Мне не нравится хД) Я вообще такой изврат стараюсь нигде кроме денвера не применять - не знаю почему, наверное интуиция...

sdaprel:
прописать в файле функцию которая на 29 секунде будет делать get запрос к самой себе и на этом заканчивать свою работу, предварительно записав результат работы в файл tmp, где писать на каком этапе завершил свою работу. При вызове самого себя читает конфиг из тмп и продолжает качать дальше. Как так, думаю можно реализовать данную задачу

На самом деле я и планировал сделать примерно это, просто вышеуказанный кусок кода доказал свою работоспособность и я не заморачиваюсь теперь хД

Точно! сча попробую)

---------- Добавлено 25.02.2013 в 15:52 ----------

РАБОТАЕТ!!! Урааа)

Тестил вот этим:


single_rec(0);
echo "sucess";

function single_rec($i){
if($i<5){
sleep(20);
return single_rec($i+1);
}else return 0;
}


---------- Добавлено 25.02.2013 в 15:54 ----------

Есть у подобного подхода "подводные камни"?

Всем спасибо, уже написал хД Скоро буду рекурсию организовывать и прочие блага. Кому интересно писал по одкопанному где-то в глубинах гугла куску кода:

ссылка - http://marc.info/?l=php-general&m=117244455625774

Прошу прощения. Все вкурил тему)

Помогите плз. Пишу батч, такого вида:


function my_function_2(&$context) {
$data = object_from_file(drupal_get_path('module', 'rmodule') . "/includes/data/authors.txt");
if (empty($context['sandbox'])) {
$context['sandbox']['progress'] = 0;
$context['sandbox']['max'] = count($data);
}
$limit = 1;
if(empty($context['sandbox']['items'])) {
$context['sandbox']['items'] = $data;//чо-то типа жизнь проходит мимо...(Витя Ак)
}


// Убираем из массива с данными уже обработанные материалы

$counter = 0;

foreach ($context['sandbox']['items'] as $item) {
sleep(1);//чтобы быстро не мотало
$file_patch = drupal_get_path('module', 'rmodule') . "/" . $item['img_url'];
$file = (object) array(
'uid' => 1,
'status' => 1
);
$file->filename = basename($file_patch);
$file->uri = $file_patch;
//file_copy($file,"public://");

go_something($file);
//$context['results'][] = $file_patch . ' : ' . $item['title'];

$counter++;
$context['sandbox']['progress']++;
$context['message'] = $item['title'];
$context['results']['processed'] = $context['sandbox']['progress'];
}
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
}

И вот что вылазит

An AJAX HTTP error occurred. HTTP Result Code: 200 Debugging information follows. Path: /batch?id=108&op=do StatusText: OK ResponseText: Fatal error: Maximum execution time of 90 seconds exceeded in Z:\home\test1.ru\www\sites\all\modules\rmodule\includes\add_data.batch.inc on line 21

Вроде бы батч он на то и батч чтобы обходить Maximum execution time и прочую ерунду. Что делать? может я где-то не верно в коде написал?

Всего: 145