【问题标题】:Playing a video from memory播放内存中的视频
【发布时间】:2014-05-06 08:28:00
【问题描述】:

是否可以使用 MemoryFile 类直接从内存中播放视频?我试过了:

AssetFileDescriptor afd = getResources().openRawResourceFd(videoResId);
InputStream is = getResources().openRawResource(videoResId);
// BufferedReader br = new BufferedReader(new InputStreamReader(is));
try {
    memoryFile = new MemoryFile("myvideo", (int) afd.getDeclaredLength());
    byte[] buffer = new byte[8192];
    int bytesRead, totalBytesRead = 0;
    while ((bytesRead = is.read(buffer)) != -1) {
        memoryFile.writeBytes(buffer, 0, 0, bytesRead);
        totalBytesRead += bytesRead;
    }
    is.close();
} catch (IOException e) {
    e.printStackTrace();
}
FileDescriptor mfd = MemoryFileUtil.getFileDescriptor(memoryFile);

videoPlayer = new MediaPlayer();
try {
    // videoPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
    videoPlayer.setDataSource(mfd, 0, afd.getLength());
    videoPlayer.prepare();
} catch (Throwable e) {
    e.printStackTrace();
}
videoPlayer.setLooping(true);
_setPlayerSurface(videoPlayer, holder);

MemoryFileUtil 类来自https://code.google.com/p/sunnykwong/source/browse/trunk/One+More+Clock/src/com/sunnykwong/omc/MemoryFileUtil.java?spec=svn699&r=699

但是表面仍然是黑色的。但是,如果我用afd AssetFileDescriptor(上面的注释行)调用setDataSource(),它就可以完美地工作。

我对 MemoryFile 做错了吗?是否有一些我需要重置的指针?

【问题讨论】:

    标签: android android-mediaplayer android-assets


    【解决方案1】:

    我怀疑 MemoryFile 是否可以工作。在深入研究MediaPlayer#setDataSource 代码后,我最终找到了native source

    status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64_t length)
    {
        ALOGV("setDataSource fd=%d, offset=%lld, length=%lld", fd, offset, length);
        struct stat sb;
        int ret = fstat(fd, &sb);
        if (ret != 0) {
            ALOGE("fstat(%d) failed: %d, %s", fd, ret, strerror(errno));
            return UNKNOWN_ERROR;
        }
    
        ALOGV("st_dev  = %llu", sb.st_dev);
        ALOGV("st_mode = %u", sb.st_mode);
        ALOGV("st_uid  = %lu", sb.st_uid);
        ALOGV("st_gid  = %lu", sb.st_gid);
        ALOGV("st_size = %llu", sb.st_size);
    
        if (offset >= sb.st_size) {
            ALOGE("offset error");
            ::close(fd);
            return UNKNOWN_ERROR;
        }
        if (offset + length > sb.st_size) {
            length = sb.st_size - offset;
            ALOGV("calculated length = %lld", length);
        }
        // ...
    

    在内部,fstat 是您传递给它的文件描述符。我怀疑这个调​​用要么完全失败,要么返回错误的大小,例如0.

    【讨论】:

      猜你喜欢
      • 2012-09-06
      • 2015-07-01
      • 2011-10-11
      • 1970-01-01
      • 1970-01-01
      • 2013-03-05
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      相关资源
      最近更新 更多