1.ffmpeg支持CONFIG_PIPE_PROTOCOL协议,说白了就是命令管道的使用。
pipe的使用和file的使用是一样的,不同的一点在于file是可以去不断的去读取和seek的,这样在ffmpeg中就会把pipe协议当成一种流媒体来处理。
也就是URLContext->is_streamed的类型。
2.在什么情况下使用ffmpeg的pipe呢?
现在android上最常见的播放流媒体的方式有两种,一种是file的方式,一种就是网络的形式。但是现在类似IPTV的数据处理不是这两种方式,需要实现数据的实时输出。这种是APK通过各种协议把数据处理完以后传递下来的,用传统的两种方式并没有办法管理这些数据,这个时候就需要使用的ffmpeg的pipe功能了。
3.先完成两个可执行文件,完成基于linux下的pipe的动能。
3.1 以下代码实现有名管道的写入功能(TestWriteBin)
#define FIFO_NAME "/data/iptv_hls_pipe"
int main()
{
FILE* file = NULL;
int fifo_fd;
if(access(FIFO_NAME, F_OK) == -1)
{
fifo_fd = mkfifo(FIFO_NAME, 0777);
if(fifo_fd <0)
{
return 0;
}
}
fifo_fd = open(FIFO_NAME, O_WRONLY);
char* tempBuffer = NULL;
{
file = fopen("/mnt/sdcard/Sample.ts","rb");
if(file == NULL)
{
return -1;
}
tempBuffer = (char*)malloc(1024);
if(tempBuffer == NULL)
{
return -1;
}
while(0==feof(file))
{
size_t n = fread(tempBuffer,1,1024,file);
size_t num =write(fifo_fd, tempBuffer, n);
while (num == -1)
{
num = write(fifo_fd, tempBuffer, n);
}
}
fclose(file);
}
free(tempBuffer);
return 0;
}
3.2 以下代码实现有名管道的读取功能(TestReadBin)
#define FIFO_NAME "/data/iptv_hls_pipe"
int main()
{
FILE* file = NULL;
int fifo_fd;
if(access(FIFO_NAME, F_OK) == -1)
{
fifo_fd = mkfifo(FIFO_NAME, 0666);
if (fifo_fd <0)
{
return 0;
}
}
fifo_fd = open(FIFO_NAME, O_RDONLY);
char* tempBuffer = NULL;
{
file = fopen("/mnt/sdcard/test_read.ts","a+");
if(file == NULL)
{
return -1;
}
tempBuffer = (char*)malloc(1024);
if(tempBuffer == NULL)
{
return -1;
}
size_t num;
while(num)
{
num = read(fifo_fd,tempBuffer,1024);
if (num > 0)
{
size_t n = fwrite(tempBuffer,1,1024,file);
}
}
}
fclose(file);
free(tempBuffer);
return 0;
}
4.在android4.1上实现基于pipe的mediaplayer播放(TestMediaPlayer)
sp mFlingerSurface;
sp mSession;
int main(int argc, char** argv)
{
MediaPlayer *mp = new MediaPlayer();
mSession = new SurfaceComposerClient();
DisplayInfo dinfo;
status_t status = mSession->getDisplayInfo(0, &dinfo);
if (status)
return -1;
// create the native surface
ALOGE("dinfo.w = %d, dinfo.h = %d", dinfo.w, dinfo.h);
sp cOntrol= mSession->createSurface(
0, dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
//4.1的实现
mSession->openGlobalTransaction();
control->setLayer(0x40000000);
mSession->closeGlobalTransaction();
sp s = control->getSurface();
//sp s = control->getSurfaceTexture();
sp proc(ProcessState::self());
ProcessState::self()->startThreadPool();
mp->setDataSource("/data/iptv_hls_pipe", NULL);
//mp->setDataSource("/mnt/sdcard/Sample.ts", NULL);
mp->prepare();
mp->setVideoSurfaceTexture(s->getSurfaceTexture()) ;
mp->start();
while(1)
{
usleep(1000000);
}
IPCThreadState::self()->joinThreadPool();
return 0;
}
5.只要实现了TestWriteBin和TestMediaplayer就可以模拟完成类似IPTV流媒体的播放。
有不明白的地方或需要源代码的,欢迎交流。本人QQ:2913712548.