2014-03-27 57 views
2

使用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有問題嗎?有一些指針需要重置嗎?

回答

0

我懷疑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.