基于QGraphicsItem的字幕翻转动画效果

OS: mac os x 10.7.5 QT: 5.0.1

main.cpp

#include "mainwindow.h"
#include <QApplication>
#include <QGraphicsScene>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    TxtItem txtItem;
    txtItem.setText("How are you, my friend!!");

    QGraphicsScene scene;
    MyQView mqv(&scene);

    scene.addItem(&txtItem);

    mqv.show();

    return a.exec();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QGraphicsView>
#include <QGraphicsItem>
#include <QTimer>

class MyQView : public QGraphicsView {
    Q_OBJECT
public:
    MyQView(QGraphicsScene *scene);
    ~MyQView();
};

class TxtItem : public QObject, public QGraphicsItem {
    Q_OBJECT
public:
    explicit TxtItem(QGraphicsItem *parent = 0);
    ~TxtItem();

   void paint(QPainter * painter,
              const QStyleOptionGraphicsItem * option,
              QWidget * widget = 0);
   QRectF boundingRect () const;
   void setText(const QString &newText);

public slots:
   void flip();

private slots:
   void animateFilp();

private:
    QTimer *tm;
    int m_angle;   //rotation angle
    int m_delta;
    int m_current; //store rotation direction
    QString m_text;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include <QTimer>

MyQView::MyQView(QGraphicsScene *scene) : QGraphicsView(scene) {
    setGeometry(100, 100, 800, 600);
    setWindowFlags(Qt::FramelessWindowHint);
}

MyQView::~MyQView() {

}

TxtItem::TxtItem(QGraphicsItem *parent)
    : QGraphicsItem(parent) {

    m_angle = 0;
    m_delta = 0;
    m_current = 0;
    setOpacity(0.5);

    tm = new QTimer;
    tm->setInterval(2000);
    connect(tm, SIGNAL(timeout()), this, SLOT(flip()));
    tm->start();
}

TxtItem::~TxtItem() {
    tm->stop();
    delete tm;
}

void TxtItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
    QBrush brush(Qt::blue);
    painter->setBrush(brush);

    painter->drawRect(boundingRect());
    painter->setPen(QPen(Qt::red, 10));
    painter->drawText(boundingRect().x(), boundingRect().y(),
                      boundingRect().width(), boundingRect().height(),
                      Qt::AlignLeft | Qt::AlignVCenter, m_text);
}

QRectF TxtItem::boundingRect() const {
    return QRectF(0, 0, 600, 300);
}

void TxtItem::setText(const QString &newText) {
    m_text = newText;
}

void TxtItem::animateFilp() {
    m_angle += m_delta;

    if(180 == m_angle) {
        m_current ^= 1;
    }

    QRectF r = boundingRect();
    setTransform(QTransform()
                 .translate(r.width() / 2, r.height() /2)
                 .rotate(m_angle, Qt::XAxis)
                 .translate(-r.width() / 2, -r.height() / 2));
    if((0 == m_current && m_angle > 0) || (1 == m_current && m_angle < 360)) {
        QTimer::singleShot(25, this, SLOT(animateFilp()));
    }
}

void TxtItem::flip() {
    m_delta = (m_current == 0 ? 9 : -9);
    animateFilp();
}

linux socket常规操作

/*server*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/wait.h>

#define PORT 3333
#define BACKLOG 10
#define DATASIZE 10

int main(int argc, char **argv) {
	int sockfd, client_fd;
	struct sockaddr_in serv_addr;
	struct sockaddr_in remote_addr;
	char buf[DATASIZE];
	int recv_len;

	if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		perror("socket error");
		exit(1);
	}

	bzero(&(serv_addr), sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(PORT);
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

	int opt = 1;
	if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt, sizeof(int)) == -1) {
		perror("setsocket error");
		exit(1);
	}

	if(bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(struct sockaddr)) == -1) {
		perror("bind error");
		exit(1);
	}

	if(listen(sockfd, BACKLOG) == -1) {
		perror("listen error");
		exit(1);
	}

	size_t sin_size = sizeof(struct sockaddr_in);
	if((client_fd = accept(sockfd, (struct sockaddr*)&remote_addr, &sin_size)) == -1) {
		perror("accept error");
		exit(1);
	}
	printf("receive a connection from %s\n", inet_ntoa(remote_addr.sin_addr));

	while(1) {
		bzero(buf, sizeof(buf));
		recv_len = recv(client_fd, buf, DATASIZE, 0);
		//buf[DATASIZE] = '\n';
		fprintf(stdout, "%s", buf);
	}
	close(sockfd);
}
telnet localhost 3333
/*client*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

#define PORT 3333
#define MAXDATASIZE 100

int main(int argc, char **argv) {
	int sockfd, recvbytes;
	char buf[MAXDATASIZE];
	struct sockaddr_in serv_addr;
	struct hostent *host;

	if(argc < 2) {
		fprintf(stderr, "Please enter the server's hostname\n");
		exit(1);
	}

	if((host = gethostbyname(argv[1])) == NULL) {
		perror("gethostbyname error");
		exit(1);
	}

	printf("host name: %s\n", host->h_name);
	printf("host address: %s\n", inet_ntoa(*((struct in_addr*)host->h_addr)));

	if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		perror("socket error");
		exit(1);
	}

	bzero(&serv_addr, sizeof(struct sockaddr_in));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(PORT);
	serv_addr.sin_addr = *((struct in_addr*)host->h_addr);

	if(connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(struct sockaddr)) == -1) {
		perror("bind error");
		exit(1);
	}

	if((recvbytes = recv(sockfd, buf, MAXDATASIZE, 0)) == -1) {
		perror("recv error");
		exit(1);
	}

	buf[recvbytes] = '\0';
	printf("Recvived: %s", buf);

	close(sockfd);
}

失落的世界

Alt none

尾声 乔布斯传

Alt none

基于FFMPEG的流媒体服务器

OS:ubuntu 12.04

ffmpeg:N-47141-g4063bb2

x264:0.133.2334 a3ac64b

目标: 使用ffserver建立流媒体服务器 使用ffmpeg对本地文件流化(x264编码器) 使用ffplay播放

ffserver.conf配置

Port 8090  #访问端口
RTSPPort 554 #rtsp端口
BindAddress 0.0.0.0 #服务器地址绑定
MaxHTTPConnections 2000 #允许的最大连接数
MaxClients 1000 #最大的客户数
MaxBandwidth 10000
CustomLog -

<Feed feed1.ffm>
File /tmp/feed1.ffm
FileMaxSize 1G
ACL allow 127.0.0.1 #只允许本地连接
</Feed>

################ asf ################

<Stream test.asf>
Feed feed1.ffm
Format asf #流媒体格式
VideoCodec libx264 #编码格式
VideoFrameRate 25 #桢率
VideoSize 1024x768 #播放大小
VideoBitRate 2M #码率
VideoBufferSize 10000000
VideoGopSize 24
StartSendOnKey
Preroll 5
#使用x264编码时必须有下面的4个参数
VideoQMin 3
VideoQMax 31
AVOptionVideo flags +global_header
AVOptionAudio flags +global_header
NOAudio
</Stream>

################ flv ################

<Stream test.flv>

Feed feed1.ffm
Format flv 

NoAudio
#AudioBitRate  32  
#AudioChannels 2
#AudioSampleRate  44100
#AVOptionAudio flags +global_header
#AudioCodec libmp3lame 

#NoVideo
VideoBitRate  1024 
VideoFrameRate  40  
VideoSize 1280x720 
VideoBufferSize 1000000
VideoCodec libx264 

VideoQMin 3 
VideoQMax 31  

VideoBitRateTolerance 100 
VideoGopSize 12  
StartSendOnKey

AVOptionVideo qmin 3
AVOptionVideo qmax 31
#AVOptionVideo quality good
#AVOptionVideo cpu-used 0
AVOptionVideo flags +global_header
#AVOptionVideo keyint_min 25
#AVOptionVideo qcomp 0.6
AVOptionVideo qdiff 4
#AVOptionVideo me_range 16
#Preroll 15
</Stream>

################ rtsp ################

<Stream live.h264>
Format rtp
Feed feed1.ffm
VideoCodec libx264
#VideoFrameRate 7
VideoBitRate 300
#VideoSize 480x272
VideoSize 352x288
#AVPresetVideo default
AVPresetVideo superfast
AVOptionVideo flags +global_header

PixelFormat yuv420p
AVOptionVideo me_range 4
AVOptionVideo qdiff 4
AVOptionVideo qmin 2
AVOptionVideo qmax 51

#MulticastAddress 224.124.0.1
#MulticastPort 5000
#MulticastTTL 1

NoAudio
#AudioCodec libfaac
#AudioBitRate 32
#AudioChannels 2
#AudioSampleRate 22050
#AVOptionAudio flags +global_header
</Stream>

################ html ################

<Stream stat.html>
Format status
# Only allow local people to get the status
ACL allow localhost
ACL allow 192.168.0.0 192.168.255.255
#FaviconURL http://pond1.gladstonefamily.net:8080/favicon.ico
</Stream>

# Redirect index.html to the appropriate site
<Redirect index.html>
URL http://www.ffmpeg.org/
</Redirect>

启动ffserver服务器

ffserver -d -f ./ffserver.conf

使用ffmpeg对本地文件流化

./ffmpeg -i  ./1.mov -vcodec libx264  -qmin 3 -qmax 31 -qdiff 4 -me_range 16 -keyint_min 25 -qcomp 0.6 -b 9000K    http://localhost:8090/feed1.ffm

捕捉本地摄像头数据

./ffmpeg -f video4linux2 -i /dev/video0 http://localhost:8090/feed1.ffm 

为流媒体增加声音

在ffmserver.conf中打开声音:

#NoAudio
AudioBitRate  128kb 
AudioChannels 2 
AudioSampleRate 44100 
AVOptionAudio flags +global_header

在输入中加入声音捕获:

ffmpeg  -f v4l2 -i  /dev/video0  -f alsa  -i hw:0,0 http://localhost:8090/feed_tv.ffm

使用ffplay播放

./ffplay  mmsh://localhost:8090/test.asf
./ffplay  http://localhost:8090/test.flv
./ffplay  rtsp://localhost:554/live.h264

git: https://github.com/lnmcc/multi_stream_server.git