Android 播放SMB共享视频

表面上看MediaPlayer只能播放本地和http协议视频。没有直接支持smb://协议。那还能播放smb视频呢?也可以的!

MediaPlayer有一个方法叫:setDataSource(MediaDataSource)。

java 复制代码
    /**
     * Sets the data source (MediaDataSource) to use.
     *
     * @param dataSource the MediaDataSource for the media you want to play
     * @throws IllegalStateException if it is called in an invalid state
     * @throws IllegalArgumentException if dataSource is not a valid MediaDataSource
     */
    public void setDataSource(MediaDataSource dataSource)
            throws IllegalArgumentException, IllegalStateException {
        _setDataSource(dataSource);
    }

我们只要实现MediaDataSource这个接口就可以了。

java 复制代码
/**
 * For supplying media data to the framework. Implement this if your app has
 * special requirements for the way media data is obtained.
 *
 * <p class="note">Methods of this interface may be called on multiple different
 * threads. There will be a thread synchronization point between each call to ensure that
 * modifications to the state of your MediaDataSource are visible to future calls. This means
 * you don't need to do your own synchronization unless you're modifying the
 * MediaDataSource from another thread while it's being used by the framework.</p>
 */
public abstract class MediaDataSource implements Closeable {
    /**
     * Called to request data from the given position.
     *
     * Implementations should fill {@code buffer} with up to {@code size}
     * bytes of data, and return the number of valid bytes in the buffer.
     *
     * Return {@code 0} if size is zero (thus no bytes are read).
     *
     * Return {@code -1} to indicate that end of stream is reached.
     *
     * @param position the position in the data source to read from.
     * @param buffer the buffer to read the data into.
     * @param offset the offset within buffer to read the data into.
     * @param size the number of bytes to read.
     * @throws IOException on fatal errors.
     * @return the number of bytes read, or -1 if end of stream is reached.
     */
    public abstract int readAt(long position, byte[] buffer, int offset, int size)
            throws IOException;

    /**
     * Called to get the size of the data source.
     *
     * @throws IOException on fatal errors
     * @return the size of data source in bytes, or -1 if the size is unknown.
     */
    public abstract long getSize() throws IOException;
}

下面是我实现的代码:

java 复制代码
public class CustomMediaDataSource extends MediaDataSource {
    private static Logger Log4j = Logger.getLogger(CustomMediaDataSource.class);
    private SmbRandomAccessFile mFile; // must not Main UI thread.
    private long mFileSize;

    public CustomMediaDataSource(SmbRandomAccessFile smbFile, long size) throws SmbException {
        this.mFile = smbFile;
        mFileSize = size;
    }

    @Override
    public int readAt(long position, byte[] buffer, int offset, int size) throws IOException {
        if (mFile.getFilePointer() != position)
            mFile.seek(position);

        if (size <= 0)
            return 0;

        Log4j.info("CustomMediaDataSource, readAt, position:" + position);
        return mFile.read(buffer, 0, size);
    }

    @Override
    public long getSize() throws IOException {
        return mFileSize;
    }

    @Override
    public void close() throws IOException {
        mFileSize = 0;
        if (mFile != null) {
            mFile.close();
            mFile = null;
        }
    }
}

这里有一个小插曲, 导致花费了大半天时间。视频播放不能用InputStream接口,要用RandomAccess接口。因为视频播放的数据不是按顺序取的。不然就会报错:java.io.IOException: Prepare failed.: status=0x1。

如果你是其他播放器的, 同样也会有这样的接口提供给你。比如ljkPlayer等。

这个主题值得写一下,网上基本没有讲到。

相关推荐
AI直播技术杂谈12 分钟前
多路数字人直播的算力调度方案对比:单卡、多卡与分布式
ai·音视频
m0_614523558 小时前
普通视频怎么做多场景一镜到底:路线设计、逐段衔接与整体验收
人工智能·音视频
Pocker_Spades_A13 小时前
视频不用再一张张截图:ClipSketch AI 把关键画面转成漫画,还能顺手生成文案
人工智能·音视频
星辰徐哥13 小时前
本地视频预览别只自己看:把Remotion动效项目发给客户远程验收
docker·ai·node.js·html·音视频·react·remotion
镜像视界(浙江)科技有限公司13 小时前
《视频孪生之上:二维展示终结,三维空间计算重构城市逻辑》——跨摄像连续表达 × 三角测量厘米级定位 × 动态轨迹建模,构建新一代城市空间
大数据·人工智能·算法·矩阵·音视频·空间计算
你不是我我14 小时前
【AI 测评】想用自己的声音给视频配音?Index-TTS本地部署这样做
人工智能·音视频
Ulyanov17 小时前
AudioVision Pro:基于 PySide6 + sounddevice 的实时音频可视化播放器设计
python·算法·音视频
福大大架构师每日一题17 小时前
ComfyUI v0.34.0发布:视频、音频、三维、显存与合作节点全面更新
音视频
敲代码的嘎仔20 小时前
用 Redis 合并写 + DelayQueue 延迟检测,把视频播放进度写库频率降到 1/60
java·开发语言·数据库·redis·缓存·音视频·高并发
Xxtaoaooo21 小时前
AI 视频生成能不能真正跑通?MoneyPrinterTurbo 本地制作、远程访问与授权验证
人工智能·音视频·cpolar·ai视频·自动化短视频