2009-03-02

Как сделать скриншот из flv файла

1. Ставим на сервер ffmpeg
    > svn checkout svn://svn.ffmpeg.org/ffmpeg/trunk ./ffmpeg
    > cd ./ffmpeg
    > ./configure
    > make
    > make install

2. Для создания GD картинки можно использовать, например вот такую функцию:

function Video2GD($filename){
  $descriptors = array(
    0 => array("pipe","r"),
    1 => array("pipe","w"),
    2 => array("pipe","w")
  );
  $cmd = 'ffmpeg -i '.$filename.' -vframes 1 -f image2 /dev/stdout';
  $cwd = '/tmp';
  $env = array();
  $process = proc_open($cmd, $descriptors, $pipes );

  if (is_resource($process)) {
    fclose($pipes[0]);
    $data = stream_get_contents($pipes[1]);
    fclose($pipes[1]);
    $error = stream_get_contents($pipes[2]);
    fclose($pipes[2]);
    return imagecreatefromstring($data);
  }
  return false;
}

пример использования функции Video2Gd:

    $im = Video2GD('/yourvideofile.flv');
    header('Content-Type: image/png');
    imagepng($im);
 

Коментариев: 2

 
  2009-02-27

Перегрузка операторов в Python

Оказывается перегрузка операторов есть не только в C++, но и в Питоне тоже...

A class can implement certain operations that are invoked by special syntax (such as arithmetic operations or subscripting and slicing) by defining methods with special names.This is Python's approach to operator overloading, allowing classes to define their own behavior with respect to language operators.

 

 

Оставить комментарий

 
  2009-02-15

Отладка PHP скриптов

Оказывается отлаживать приложения на PHP возможно если вы используете Eclipse c PDT, для этого необходимо скачать Studio Web Debugger - эта штука ставится как расширение PHP и позволяет эклипсу останавливаться на ваших точках остановки, проходить приложение по шагам, смотреть значения переменных и еще много чего. Радует то, что как Eclipse, так и Debugger доступны для различных платформ, и совершенно бесплатны, вот уж где коммунизм наступил...

 

Оставить комментарий

 
  2009-02-04

Редактор для Python

Попробовав несколько разных радакторов пришел к выводу что для меня лучше чем Eclipse с плагином PyDev ничего не придумано.

 

Коментариев: 2

 
  2009-02-04

Простой вебсервер на Питоне

Возникла необходимость сделать простой вебcервер, но чтобы он был максимально легкий и быстрый. После некоторых размышлений решил реализовать его на Питоне, первоначально в качестве кандидатов рассматривались PHP, Java, Perl, но в конечном итоге решил остановиться на Python.

Приведенный пример работает на Python 2.5, хотя первоначально был сделан на Python 3. Питон выбрал потому что во первых хотелось посмотреть что это за зверь такой, что его так любят разработчики Google a во вторых понравилось что можно с легкостью создавать многонитивые приложения.

Синтаксис языка оказался довольно забавный, так как в нем нет операторных скобок так что тем кто любит сравнивать фигурные скобки Си с паскалевским begin/end останутся без темы для споров - операторных скобок нет как класса.

Понравилась философия разработчиков Battaries Included - например разработчику для создания простого вебсервера не нужно вникать в тонкости протоколов - достаточно взять один из готовых классов. Однако по какой то странной причине разработчики Питона не любят реляционные базы данных, например нет в Питоне интерфейса к MySQL а сторонние разработкики делают расширения весьма неохотно, поэтому третью версию питона с MySQL никак не соединить - максимум что позволено версия 2.5 и когда будет поддержка для третьей - неизвестно.

#! /usr/local/bin/python

import BaseHTTPServer
import cgi
import string

class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def showPage(self,method,get_data,post_data):
        self.wfile.write("HTTP/1.1 200 OK\n");
        self.wfile.write("Content-Type: text/html\n")
        self.wfile.write("\n");        

        responce = """
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Simple HTTP Server</title>
<meta name="description" content="Simple HTTP Server" />
</head>
<body style="background:white;">				
Method $method<br />
Path: $path<br />
get data $get_data<br />
post data $post_data<br />

<form action="" method="post">
<input type="text" name="value1">
<input type="submit" name="value2">
</form>
</body>
</html>
        """
        s = string.Template(responce)
        responce = s.substitute(dict(
            get_data=get_data,
            post_data=post_data,
            path=self.path,
            method=method
            )) 
        self.wfile.write(responce);
                
    def do_GET(self):
        get_data = cgi.parse_qs(self.path[2:])
        self.showPage('GET',get_data,{})
        

    def do_POST(self):
        get_data = cgi.parse_qs(self.path[2:])
        cl, cl2 = cgi.parse_header(self.headers.get('content-length'))
        qs = self.rfile.read(int(cl))
        post_data = cgi.parse_qs(qs.decode())
        self.showPage('GET',get_data,post_data)


class ChatServer(BaseHTTPServer.HTTPServer):
    def __init__(self,address,handler):
        BaseHTTPServer.HTTPServer.__init__(self,address,handler)
        

def main():
    try:
        server = ChatServer(('localhost', 8080), RequestHandler)
        server.serve_forever()
    except KeyboardInterrupt:
        print('^C received, shutting down server')
        server.socket.close();

if __name__ == '__main__':
    main()

 

 

Коментариев: 14

 
  2009-01-27

Browser Detection

Обнаружил что фрагмент кода из mootools выдает какой то странный результат для версии движка, может я не знаю каких нюансов, но все же хочется чтобы версия хоть как то коррелировала с версией браузера, кроме того писать каждый раз Browser.Engine.presto довольно длинно, хотелось бы чтобы было просто Browser.presto.

Mootools в отличие от jQuery и prototype определяет тип движка браузера по определенным особенностям объектной модели а не по navigator.userAgent, это неплохо, вот только версию движка таким образом можно определить очень приблизительно, поэтому версию будет логично определять по navigator.userAgent а сам движок по функционалу объектной модели.

Немного похозяйничав в коде получилось вот что:

var Browser = {	
	platform: (navigator.platform.match(/mac|win|linux/i) || ['other'])[0].toLowerCase(),
	version: (navigator.userAgent.toLowerCase().match(/.+(?:rv|it|ra|ie|me)[\/: ]([\d.]+)/) || [-1,-1])[1]
};

if (window.opera) Browser.presto = true;
else if (window.ActiveXObject) Browser.trident = true;
else if (!navigator.taintEnabled) Browser.webkit = true;
else if (document.getBoxObjectFor != null) Browser.gecko = true;

Ваш браузер:

Версия  
Платформа  
trident (IE)  
presto (Opera)  
webkit (Safary, Chrome)  
gecko (Firefox, Mozilla)  
 

Оставить комментарий

 
  2009-01-04

Текстовый редактор для Nokia 5800

Я уже писал, что у Nokia 5800 наблюдается некоторый дефицит офисных программ. Странно, но даже обычный текстовый редактор для мобильника найти не так то просто, хотя создать некое подобие notepad'a проще простого.

Немного поколдовав с Sun Java Wireless Toolkit, сделал небольшой текстовый редактор для своего мобильника который умеет читать, редактировать и сохранять текстовые UTF-8 файлы.

Отсюда  можно скачать TextEditor.jar. Исходники редактора можно скачать здесь.

В принципе, программа должна запуститься на любом мобильнике с Java и файловой системой к коим относятся практически все Symbian и Windows Mobile устройства.

К сожалению, jar не подписан, поэтому при работе приложение выдает кучу дурацких предупреждений, как с этим справиться я пока не придумал, в крайнем случае придется покупать сертификат, а это довольно дорого  Может кто знает более дешевый способ? Он должен, должен быть это способ, его не может не быть.

UPD: Для установки - скачиваем TextEditor.jar, кладем на флешку телефона, предаварительно подключив телефон к компьютеру, можно сразу скачать jar через встроенный браузер телефона. Запускаем jar через встроенный файловый менеджер телефона. Соглашаемся со всеми варнингами - после установки в телефоне в списке приложений появится значёк запускающий текстовый редактор.

 

Коментариев: 20

 
  2008-12-30

Скрипт для генерации снега

Сегодня один из заказчиков попросил поставить на сайт снежинки - да да старые добрые снежинки которые вот уже которые год падают на сайтах в новогоднюю ночь.

Сначало было откопали один из старых скриптов для создания эффекта падающих снежинок, долго его настраивали потом выкинули нафиг и за полчаса написали свой, с классами, минифицированная версия весит 6K - можно еще уменьшить, но я не особо старался удалить все неиспользуемые функции - это ведь только на новогодние праздники - потом уберем до следующего года.

Отсюда можно скачать наш скрипт для генерации снежинок. Если кликнуть на ссылку то можно посмотреть скрипт в действии. Скрипт очень простой, если захотите использовать нужно будет изменить путь к файлам со снежинками, ну и коничество и форму снежинок можно подобрать по вкусу.

 

Читать далее...

 

Оставить комментарий

 
  2008-12-19

Ограничение области видимости в JavaScript

Иногда в JavaScript нужно создать пару методов которые должны быть видны только изнутри определенного куска кода. Для этого достаточно внести эти методы внутрь анонимной функции и сразу ее выполнить:

(function(){ //наша анонимная функция
function func1(){ //первая функция видимость которой нужно ограничить
   alert('!');
}

function func2(){ //вторая функция видимость которой нужно ограничить    
   func1();
}
func2();
//внутри блока func1 и func2 "видят" друг друга и могут быть вызваны!
})(); //выполнить

//при этом вне блока func1 и func2 оказываются невидны!

Этот принцип может быть также использован для создания приватных методов и свойств при программировании объектов.

 

Оставить комментарий

 
  2008-12-19

Корректный способ итерации сквозь объекты

JavaScript удивительно мощный язык и, пожалуй самой мощным его свойством является возможность динамического конструирования объектов. Одной из часто встречающихся задач возникающих при работе с JavaScript является итерация по всем элементам объекта.

Допустим, у нас есть объект созданный вот таким образом:

var obj = {property1:"свойство 1",property2:"свойство 2"};

вот самый распространенный НЕПРАВИЛЬНЫЙ способ показать все свойства объекта:

for(key in obj){
        alert(key);
}

Вроде все работает правильно и на экране действительно последовательно покажутся все свойства объекта. Почему такой способ является неправильным?

Добавим перед циклом вот такую строчку:

Object.prototype['test1'] = "test1 value";

При запуске скрипта еще раз оказывается, что наш объект волшебным образом приобретает еще одно свойство - test1, хотя мы его не создавали! Это значит что любая сторонняя библиотека которая таким способом расширяет функциональность стандартных классов JavaScript, например prototype.js способна непредсказуем образом изменить логику работы ваших программ. В данном случае хорошим тоном является сравнение текущего свойства и свойства прототипа при каждой итерации, если они равны, значит ничего не делаем:

for(key in obj){
   if (obj.constructor.prototype[key]!==obj[key]){
      alert(obj[key]);
   }
}

Обратите внимание, что здесь использовано строгое сравнение !==. Все просто, все логично, вот только набирать это каждый раз довольно утомительно, поэтому создадим вот такую функцию:

    function forEach(obj,fn){
        for(key in obj){
            if (obj.constructor.prototype[key]!==obj[key]){
                if (fn(key)===false) break;
            }
        }
    }

В этом случае итерация запишется совсем просто:

forEach(obj,function(key){
    alert(obj['key']);
});

Обратите внимание, что в функции forEach есть возможность остановить итерацию досрочно, что бывает полезно например при поиске элемента, для этого достаточно возвратить false:

forEach(obj,function(key){
    alert(obj['key']);
    if (key=='property1') return false;
});

 

 

Оставить комментарий