4/21/2012

Звездочки рейтинга в результатх поиска Google

Наверняка многие из вас замечали, что для некоторых результатов поиска Google показывает текущий рейтинг, который соответствует данному результату на Вашем сайте. Пример того, как выводится подобный результат в Google приведен ниже:


Согласитесь, вероятность того, что такая ссылка имеет больше шансов привлечь внимание пользователя, чем стандартные результаты поиска. Добиться того, чтобы Google отображал результаты подобным образом совсем насложно, используя специальную разметку, которую кроме Google понимают Microsoft, Yahoo!, и другие поисковые системы, которая применяется для результатов рейтингов и обзорово.

Существуют несколько вариантов подобной разметки. Я ограничусь писанием одного из них, про остальные можно почитать здесь: http://support.google.com/webmasters/bin/answer.py?hl=en&answer=172705. Итак, на кадой странице, которая может иметь рейтинг, обязательно должны присутствовать следующие элементы:

1. Название объекта, который оценивается
2. Текущий средний рейтинг
3. Количество голосов или обзоров, на которых строится рейтинг.

Для этого, содержимое страницы, которое содержит информацию о рейтинге, должно быть обравлмлено в тэг с аттрибутаит itemscope и i itemtype="http://data-vocabulary.org/Review-aggregate", например:


HTML тэгу, который обрамляет заголовок объкета надо добавить аттрибут itemprop="itemreviewed". Например:

Мойка "Автобаня"


Средний рейтинг для объекта можно задать в специальном мета-тэге:



Обратите внимание, что Google оперирует шкалой рейтингов от 0 до 5. Если Вы испольщуете другую шкалу, то задать диапазон шкалы можно таким образом:

 




И наконец, количество голосов, на которых базируется рейтинг задается таким образом:

1 отзыв

Для того, чтобы удоставриться, что Вы все сделали правильно, Вам необязательно дожидаться, пока Google проиндексирует страницу. Для проверки нужно ввести ссылку Вашу страницу здесь: http://www.google.com/webmasters/tools/richsnippets

Описанный выше подход успешно применен на сайте отзывов об организациях Киева Отзычик.

Playing video in .NET Windows Forms application

I have a Windows Forms application developed in C#.NET that I used to work on a few years ago which includes functionality that is supposed to display fragments from a video file on form. Everything was fine while the application was working in Windows XP: there are a number of ways to play the video in a .NET application that worked there.One of them, that I was using, is the .NET wrapper for the native windows avifil32 library, which used to play .AVI files just fine. But this approach stopped working in Windows 7. I have also tried Managed DirectX but sing the Managed DirectX was discontinued a while back, it did not work in Windows 7 either. And since I just had to fix the issue I did not feel like rewriting the application with WPF.

Fortunately I found the library called DirectShow.NET, which provides .NET wrappers for native DirectShow calls. There are a number of examples included with the library, so getting it to work was fairly simple. Also, to make my life a little easier I wrote a simple class that allows playing Video in a given Control on a Form (I used PictureBox for this), which I would like to discuss below.

The VideoPlayer class is displayed below. The constructor of the class takes a path to the file that needs to be played and the control where the video should be displayed. The class allows to play fragments from the video starting at a given second and ending at a given second (see method SetFragment, which must be called before the Play method if you just want to play the fragment and not the entire video). There is also a SetRate method that allows to set the speed with which the video will be played.

The use of the class if fairly simple:
1. Download and link to your project the DirectShow.NET library from DirectShow.NET.
2. Copy and paste the VideoPlayer.cs class below and include it into your project.
3. Create a PictureBox control on a form (or any other control that you see fit).
4. Instantiate a VideoPlayer class, providing a path to the file and a reference to a control you just added.
5. Optionally set the frame rate and the fragment start and end positions.
6. Call Play method to start the video and Pause method to stop it.
7. Use the Close method when the video is not needed.

So here comes the code of the VideoPlayer class (a lot which is simply copied and pasted from one of the examples included with DirectShow.NET):

using System;
using System.Collections.Generic;
using System.Text;
using DirectShowLib;
using System.Windows.Forms;
using System.Runtime.InteropServices;


namespace VideoUtils
{
    public class VideoPlayer
    {

        public enum PlayState
        {
            Stopped,
            Paused,
            Running,
            Init
        };

        private Control owner;
        private string FileName;

        private IGraphBuilder graphBuilder = null;
        private IMediaControl mediaControl = null;
        private IMediaEventEx mediaEventEx = null;
        private IVideoWindow videoWindow = null;
        private IBasicAudio basicAudio = null;
        private IBasicVideo basicVideo = null;
        private IMediaSeeking mediaSeeking = null;
        private IMediaPosition mediaPosition = null;
        private IVideoFrameStep frameStep = null;

        private int currentVolume = 0;
        private PlayState currentState = PlayState.Stopped;
        public PlayState state {
            get { return currentState; }
        }

        public VideoPlayer(string file, Control owner)
        {
            this.owner = owner;
            this.FileName = file;

            this.currentState = PlayState.Stopped;
            this.currentVolume = -10000; // muting the audio

            InitializePlayer();
        }

        private void InitializePlayer()
        {
            int hr = 0;

            if (FileName == string.Empty)
                return;

            this.graphBuilder = (IGraphBuilder)new FilterGraph();

            // Have the graph builder construct its the appropriate graph automatically
            hr = this.graphBuilder.RenderFile(FileName, null);
            DsError.ThrowExceptionForHR(hr);

            // QueryInterface for DirectShow interfaces
            this.mediaControl = (IMediaControl)this.graphBuilder;
            this.mediaEventEx = (IMediaEventEx)this.graphBuilder;
            this.mediaSeeking = (IMediaSeeking)this.graphBuilder;
            this.mediaPosition = (IMediaPosition)this.graphBuilder;

            // Query for video interfaces, which may not be relevant for audio files
            this.videoWindow = this.graphBuilder as IVideoWindow;
            this.basicVideo = this.graphBuilder as IBasicVideo;

            // Query for audio interfaces, which may not be relevant for video-only files
            this.basicAudio = this.graphBuilder as IBasicAudio;

            // Have the graph signal event via window callbacks for performance
            // hr = this.mediaEventEx.SetNotifyWindow(owner, WMGraphNotify, IntPtr.Zero);
            DsError.ThrowExceptionForHR(hr);

                // Setup the video window
            hr = this.videoWindow.put_Owner(owner.Handle);
            DsError.ThrowExceptionForHR(hr);

            hr = this.videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipSiblings | WindowStyle.ClipChildren);
            DsError.ThrowExceptionForHR(hr);

            GetFrameStepInterface();

            hr = this.videoWindow.SetWindowPosition(0, 0, owner.Width, owner.Height);

            hr = this.basicAudio.put_Volume(this.currentVolume);
        }

        public void Play()
        {
            int hr = 0;
            // Run the graph to play the media file
            hr = this.mediaControl.Run();
            DsError.ThrowExceptionForHR(hr);

            this.currentState = PlayState.Running;
        }

        //
        // Some video renderers support stepping media frame by frame with the
        // IVideoFrameStep interface.  See the interface documentation for more
        // details on frame stepping.
        //
        private bool GetFrameStepInterface()
        {
            int hr = 0;

            IVideoFrameStep frameStepTest = null;

            // Get the frame step interface, if supported
            frameStepTest = (IVideoFrameStep)this.graphBuilder;

            // Check if this decoder can step
            hr = frameStepTest.CanStep(0, null);
            if (hr == 0)
            {
                this.frameStep = frameStepTest;
                return true;
            }
            else
            {
                // BUG 1560263 found by husakm (thanks)...
                // Marshal.ReleaseComObject(frameStepTest);
                this.frameStep = null;
                return false;
            }
        }

        /*
         * Media Related methods
         */

        public void Pause()
        {
            if (this.mediaControl == null)
                return;

            // Toggle play/pause behavior
            if ((this.currentState == PlayState.Paused) || (this.currentState == PlayState.Stopped))
            {
                if (this.mediaControl.Run() >= 0)
                    this.currentState = PlayState.Running;
            }
            else
            {
                if (this.mediaControl.Pause() >= 0)
                    this.currentState = PlayState.Paused;
            }
        }

        public void SetFragment(long start_seconds, long stop_seconds)
        {
            // In Directx time is measured in 100 nanoseconds. 

            DsLong pos_start = new DsLong(start_seconds * 10000000);
            DsLong pos_stop = new DsLong(stop_seconds * 10000000);
            int hr = 0;
            // Seek to the position
            hr = this.mediaSeeking.SetPositions(pos_start, AMSeekingSeekingFlags.AbsolutePositioning, pos_stop, AMSeekingSeekingFlags.AbsolutePositioning);
        }

        public void CloseFile()
        {
            int hr = 0;

            // Stop media playback
            if (this.mediaControl != null)
                hr = this.mediaControl.Stop();

            // Clear global flags
            this.currentState = PlayState.Stopped;

            // Free DirectShow interfaces
            CloseInterfaces();

            // Clear file name to allow selection of new file with open dialog

            // No current media state
            this.currentState = PlayState.Init;

        }

        private void CloseInterfaces()
        {
            int hr = 0;

            try
            {
                lock (this)
                {
                    // Relinquish ownership (IMPORTANT!) after hiding video window
                    hr = this.videoWindow.put_Visible(OABool.False);
                    DsError.ThrowExceptionForHR(hr);
                    hr = this.videoWindow.put_Owner(IntPtr.Zero);
                    DsError.ThrowExceptionForHR(hr);

                    if (this.mediaEventEx != null)
                    {
                        hr = this.mediaEventEx.SetNotifyWindow(IntPtr.Zero, 0, IntPtr.Zero);
                        DsError.ThrowExceptionForHR(hr);
                    }

                    // Release and zero DirectShow interfaces
                    if (this.mediaEventEx != null)
                        this.mediaEventEx = null;
                    if (this.mediaSeeking != null)
                        this.mediaSeeking = null;
                    if (this.mediaPosition != null)
                        this.mediaPosition = null;
                    if (this.mediaControl != null)
                        this.mediaControl = null;
                    if (this.basicAudio != null)
                        this.basicAudio = null;
                    if (this.basicVideo != null)
                        this.basicVideo = null;
                    if (this.videoWindow != null)
                        this.videoWindow = null;
                    if (this.frameStep != null)
                        this.frameStep = null;
                    if (this.graphBuilder != null)
                        Marshal.ReleaseComObject(this.graphBuilder); this.graphBuilder = null;

                    GC.Collect();
                }
            }
            catch
            {
            }
        }

        public int SetRate(double rate)
        {
            int hr = 0;

            // If the IMediaPosition interface exists, use it to set rate
            if (this.mediaPosition != null)
            {
                hr = this.mediaPosition.put_Rate(rate);
            }

            return hr;
        }

    }
}

4/18/2012

Яндекс субботник

Я.Субботник в Киеве, 5 мая

Я.Субботник в Киеве пройдет 5 мая по адресу: Киев, ул. Б.Хмельницкого, 53, отель "Опера", зал "Симфония Гранд Холл".

Регистрация на мероприятие начнется 18 апреля. Количество мест ограничено.

Для тех, кто не попадёт в число участников или не сможет лично присутствовать на Я.Субботнике, будет организована онлайн-трансляция.

Подробную информацию о мероприятии читайте здесь.

4/05/2012

Сайт-справочник организаций и предприятий Киева otzyvchik.com запущен!

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

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

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

Собственно, милости прошу. Заходите, добавляйте организации, пишите отзывы. А если вдруг вам захочется увидеть на сайте что-то новенькое пишите на info@otzyvchik.com.