在Android上运行时写入Unity的StreamingAssets文件夹?

时间:2013-11-25 09:40:05

标签: android video unity3d

所以......我的目标如下:

  1. 使用http请求下载.mp4视频。
  2. 使用www.bytes和File.WriteAllBytes()将其放入Android APK的StreamingAssets文件夹中。
  3. 使用我购买的EasyMovieTexture电影插件在Android设备上播放。
  4. 但是,当我尝试在以下路径中写入StreamingAssets文件夹时出现错误:

    jar:file:///data/app/com.catlard.testName-1.apk!/assets/ash.mp4
    

    这也是下面PlaceMovieInStreamingAssets函数中_debugString的第一个值。甚至可以在Android上运行时写入StreamingAssets文件夹吗?这是我用来做这些东西的课程。它在WriteAllBytes调用中停止 - 我知道,因为我在前后放置了print语句,这就是它停止的地方。

    using UnityEngine;
    using System.Collections;
    using System.IO;
    
    public class StartVideoFromWeb : MonoBehaviour {
    
        public string _movieFileName;
        public string _movieHTTPLocation;
        private string _debugString;
        private MediaPlayerCtrl _control;
        public float _mbFileSize = 16.7f;
        private string _movieLocationOnDevice;
    
        private float _prevProg;
    
        private WWW _movieWWW;
    
        public float _kbSpeed;
        public float _timeBetweenSpeedMeasurements = 1f;
    
        // Use this for initialization
    
        public IEnumerator Start() {
    
           yield return StartCoroutine("LoadMovie");
           PlaceMovieInStreamingAssets(_movieWWW);
           yield return new WaitForSeconds(.5f);
           //PlayMovieInCtrl(_movieHTTPLocation + _movieFileName);
           PlayMovieInCtrl(_movieLocationOnDevice);
    
           yield return 0;
        }
    
        public void PlayMovieInCtrl(string path) {
    
           _control = GetComponent<MediaPlayerCtrl>();
           _debugString = _movieFileName + " was loaded into Ctrl";
           _control.Load(path);
           renderer.material.mainTexture = _control.GetVideoTexture();
           _control.Play();
           _debugString = "Attempted to play movie at " + path  + ".";
    
        }
    
        public void PlaceMovieInStreamingAssets(WWW www) {
    
           _movieLocationOnDevice = "jar:file://" + Application.dataPath + "!/assets/" + _movieFileName;
           //_movieLocationOnDevice =  Application.persistentDataPath + "/" + _movieFileName;
           _debugString = "Failed to write to path: " + _movieLocationOnDevice;
           File.WriteAllBytes(_movieLocationOnDevice, www.bytes);
           _debugString = "Wrote file to StreamingAssets folder.";
        }
    
        public IEnumerator MeasureSpeed() {
           yield return new WaitForSeconds(_timeBetweenSpeedMeasurements);
           float tempMeasure = 0;//((_movieWWW.progress - _prevProg) * (_mbFileSize * 1024f)) * (_timeBetweenSpeedMeasurements /Time.deltaTime);
           _prevProg = _movieWWW.progress;
           if(tempMeasure > 0)
             _kbSpeed = Mathf.RoundToInt(tempMeasure);
           StartCoroutine("MeasureSpeed");
        }
    
        public IEnumerator LoadMovie () {
           string urlString = _movieHTTPLocation + _movieFileName;
           _movieWWW = new WWW(urlString);
           bool isLoaded = false;
           StartCoroutine("MeasureSpeed");
    
           while(!isLoaded && _movieWWW.error == null) {
    
             _debugString = "Movie " + Mathf.RoundToInt(_movieWWW.progress * 100f).ToString() + "%";
    
             if(_kbSpeed > 0)
              _debugString += " @ " + _kbSpeed.ToString() + "kb/sec";
    
             if(_movieWWW.progress == 1.0)
              isLoaded = true;
             yield return 0;
           }
           StopCoroutine("MeasureSpeed");
    
           if(_movieWWW.error == null)
             _debugString = "Movie loaded with no errors.";
           else
             _debugString = _movieWWW.error.ToString();
    
        }
    
        public void OnGUI() {
           GUI.Label(new Rect(0,0,700,100), _debugString);
           GUI.Label(new Rect(0,30, 400, 100), "Buffered: " + _control.GetCurrentSeekPercent().ToString());
        }
    }
    

2 个答案:

答案 0 :(得分:5)

项目声明(StreamingAssets,RawAssets等)是只读的,你不能写任何东西,而是写写内部/外部存储看看here,如果你更喜欢写c#我相信您将使用Xaramin框架

答案 1 :(得分:3)

艾哈迈德是对的,他们是只读的。但是,您可以写信至Application.persistentDataPath

我基本上对流式MP3做了同样的事情。我编写的以下脚本从Internet(一个mp3文件)中获取数据,然后将其持久化到persistentDataPath并写入字节。如果该文件已存在,则从本地路径而不是www。

中获取
using UnityEngine;
using System.Collections;
using System.Net;
using System.IO;

public class PlayMusic : MonoBehaviour {
    public string[] songs;
    public string currentSong;
    public WebClient webClient;
    public float Size = 0.0f;
    private int xRand;
    WWW request;
    byte[] fileData;

    IEnumerator loadAndPlayAudioClip(string song) {
        string path = song;
        currentSong = song;
        FileInfo info = new FileInfo(Application.persistentDataPath + "/" + xRand + "_song.mp3");
        if (info.Exists == true) {
            print("file://"+Application.persistentDataPath + "/" + xRand + "_song.mp3 exists");
            path = "file:///" + Application.persistentDataPath + "/" + xRand + "_song.mp3";
        }

        // Start a download of the given URL
        request = new WWW(path);

        yield return request;

            AudioClip audioTrack = request.GetAudioClip(false, true);
            audio.clip = audioTrack;
            audio.Play();
            Destroy(this);

    }
    void Start () {
        xRand = Random.Range(0, 11);
        StartCoroutine(loadAndPlayAudioClip(songs[xRand]));
    }
    // Update is called once per frame
    void Update () {
       print("Size: "+Size+" bytes");
       if (request.isDone) {
               fileData = request.bytes;
               Size = fileData.Length;
               if (fileData.Length > 0) {
                        File.WriteAllBytes(Application.persistentDataPath + "/" + xRand + "_song.mp3", fileData);
                        print("Saving mp3 to " + Application.persistentDataPath + "/" + xRand + "_song.mp3");
                }
       }
    }
}