iOS:如何从AVAsset或AVAssetTrack获取音频采样率

时间:2013-03-27 08:12:52

标签: ios avfoundation core-audio

加载如下的AVAsset后:

AVAsset *asset = [AVAsset assetWithURL:url];

我想知道音频轨道的采样率是多少。目前,我正在接收这样的音轨:

AVAssetTrack *audioTrack = [[asset tracksWithMediaCharacteristic:AVMediaCharacteristicAudible] objectAtIndex:0];

哪个有效。但我似乎无法找到任何类型的财产,甚至在使用谷歌后都没有;-),这给了我采样率。这是如何正常工作的?它甚至可能吗? (我开始怀疑越来越多,因为谷歌搜索没有给我很多信息......)

3 个答案:

答案 0 :(得分:4)

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.orient.OrientGraph;

public class DijkstraExcl {

    private OrientGraph         g;          //grafh DB
    private Set<String>         S;          //visited rids
    private Set<String>         T;          //to visit rids
    private Map<String,Integer> f;          //f(i)     < @rid, weight_to_get_to_@rid >
    private Map<String,String>  J;          //J(i)     < @rid, previous_node_in_the_shortest_path >
    private String              eClass;     //edge class to use
    private String              prop;       //weight property to use on the edge

    public DijkstraExcl(OrientGraph g, String e, String p){
        this.g= g;
        this.eClass = e;
        this.prop = p;
        S = new HashSet<String>();
        T = new HashSet<String>();
        f = new HashMap<String,Integer>();
        J = new HashMap<String,String>();
    }


    //private methods

    //                  (Vertex start_vertex, Vertex dest_vertex, Direction.IN/OUT/BOTH, Set of edge rids to exclude) 
    private void findPath(Vertex startV, Vertex endV, Direction dir, Set<String> excludeEdgeRids){      

    //init
        S.clear();
        T.clear();
        f.clear();
        J.clear();

    //step1
        Iterator<Vertex> vertici = g.getVertices().iterator();
        while(vertici.hasNext()){
            Vertex ver = vertici.next();
            f.put(ver.getId().toString(), Integer.MAX_VALUE);
            T.add(ver.getId().toString());
        }
        f.put(startV.getId().toString(), 0);        //f(startV) = 0
        J.put(startV.getId().toString(), null);     //J(startV) = null
        T.remove(startV.getId().toString());        //startV visited => removed from T
        S.add(startV.getId().toString());           //                                and added in S



        Iterator<Vertex> near = startV.getVertices(dir, eClass).iterator();

        while(near.hasNext()){
            Vertex vicino = near.next();
            J.put(vicino.getId().toString(), startV.getId().toString());            //J(i) = startV
            f.put(vicino.getId().toString(), weight(startV.getId().toString(), vicino.getId().toString(),dir,excludeEdgeRids));     //f(i) = weight(startV, i)
        }

    //step2
        Boolean cont = false;
        Iterator<String> t = T.iterator();
        while(t.hasNext()){
            String i = t.next();
            if(f.get(i)!=Integer.MAX_VALUE){
                cont = true;
            }
        }
        while(cont){

            String j = startV.getId().toString();
            Integer ff = Integer.MAX_VALUE;
            t = T.iterator();
            while(t.hasNext()){
                String i = t.next();
                if(f.get(i)<=ff){
                    ff = f.get(i);
                    j = i;
                }
            }
            T.remove(j);
            S.add(j);
            if(T.isEmpty()){
                break;
            }

        //step3
            near = g.getVertex(j).getVertices(dir, eClass).iterator();

            while(near.hasNext()){
                Vertex vic = near.next();
                String i = vic.getId().toString();
                if( (T.contains(i)) && (f.get(i) > (f.get(j) + weight(j,i,dir,excludeEdgeRids))) ){
                    if(weight(j,i,dir,excludeEdgeRids)==Integer.MAX_VALUE){
                        f.put(i, Integer.MAX_VALUE);
                    }else{
                    f.put(i, (f.get(j) + weight(j,i,dir,excludeEdgeRids)));
                    }
                    J.put(i, j);
                }
            }

            //shall we continue?
            cont = false;
            t = T.iterator();
            while(t.hasNext()){
                String i = t.next();
                if(f.get(i)!=Integer.MAX_VALUE){
                    cont = true;
                }
            }
        }
    }

    private int weight(String rid_a, String rid_b, Direction dir, Set<String> excl){        //in case of multiple/duplicate edges return the lightest
        Integer d = Integer.MAX_VALUE;
        Integer dd;
        rid_b = "v["+rid_b+"]";

        if(excl==null){
            excl = new HashSet<String>();
        }
        Vertex a = g.getVertex(rid_a);

        Iterator<Edge> eS = a.getEdges(dir, eClass).iterator();
        Set<Edge> goodEdges = new HashSet<Edge>();
        while(eS.hasNext()){
            Edge e = eS.next();

            if((e.getProperty("out").toString().equals(rid_b) || e.getProperty("in").toString().equals(rid_b)) && !excl.contains(e.getId().toString())){
                goodEdges.add(e);
            }
        }
        Iterator<Edge> edges= goodEdges.iterator();
        while(edges.hasNext()){
            Edge e=edges.next();
                dd = e.getProperty(prop);
                if(dd<d){
                    d=dd;
                }
        }
        return d;
    }


    //public methods

    public List<Vertex> getPath (Vertex startV, Vertex endV, Direction dir, Set<String> exclECl){
        String j,i;
        List<Vertex> ppp = new ArrayList<Vertex>();
        List<Vertex> path = new ArrayList<Vertex>();

        findPath(startV, endV, dir, exclECl);
        i = endV.getId().toString();
        path.add(endV);
        if(f.get(endV.getId().toString()) == Integer.MAX_VALUE){
            return null;
        }
        while(!i.equals(startV.getId().toString())){
            j = J.get(i);
            if(j == null){
                return null;
            }
            path.add(g.getVertex(j));
            i = j;
        }
        for(int a=0, b=path.size()-1;a<path.size();a++, b--){
            ppp.add(a, path.get(b));
        }

        return ppp;
    }

    public List<String> getPathString (Vertex startV, Vertex endV, Direction dir, Set<String> exclECl){
        List<String> pathS = new ArrayList<String>();
        List<Vertex> path = getPath(startV, endV, dir, exclECl);

        if(path == null){
            return null;
        }
        for(Vertex v : path){
            pathS.add(v.getId().toString());
        }
        return pathS;
    }

    public Integer getWeight(Vertex startV, Vertex endV, Direction dir, Set<String> exclECl){
        findPath(startV, endV, dir,exclECl);
        return f.get(endV.getId().toString());
    }
}

我使用Swift所以它看起来有点不同但它仍然可以用于Obj-C。

public class test_dijkstra {

    public static void main(String[] args) {

        String nomeDb = "dijkstra_test";

        try {
            OServerAdmin serverAdmin = new OServerAdmin("remote:localhost/"+nomeDb).connect("root", "root");
            if(serverAdmin.existsDatabase()){  // il db esiste
                //connessione a db
                OrientGraph g = new OrientGraph("remote:localhost/"+nomeDb);
                DijkstraExcl d = new DijkstraExcl(g, "arco", "peso");
                Set<String> ex =new HashSet<String>();

                //------------------------------------------------
                Vertex start = g.getVertex("#9:0");
                Vertex end = g.getVertex("#9:5");
                ex.add("#12:4");
                Direction direction = Direction.BOTH;

                System.out.println(d.getPath(start,end,direction,ex));
                System.out.println(d.getPathString(start,end,direction,ex));
                System.out.println(d.getWeight(start,end,direction,ex));
                //------------------------------------------------

                //chiude db
                g.shutdown();
            }
            else{
                System.out.println("Il database '"+ nomeDb + "' non esiste");
            }
            serverAdmin.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

似乎也给出了正确答案,但由于这个名字,我有点担心。

答案 1 :(得分:0)

找到它。我正在使用MTAudioProcessingTap,所以在prepare()函数中我可以使用:

void prepare(MTAudioProcessingTapRef tap, CMItemCount maxFrames, const AudioStreamBasicDescription *processingFormat)
{
    sampleRate = processingFormat->mSampleRate;
    NSLog(@"Preparing the Audio Tap Processor");
}

答案 2 :(得分:0)

使用Swift和AVFoundation:

let url = Bundle.main.url(forResource: "audio", withExtension: "m4a")!
let asset = AVAsset(url: url)
if let firstTrack = asset.tracks.first {
    print("bitrate: \(firstTrack.estimatedDataRate)")
}

要在元数据中查找更多信息,还可以咨询: https://developer.apple.com/documentation/avfoundation/avassettrack https://developer.apple.com/documentation/avfoundation/media_assets_playback_and_editing/finding_metadata_values