2009-06-29 62 views

回答

4

我不知道你为什么会想将音频文件存储在SQL数据库,但sqlite3的支持BLOB。因此将它们存储为BLOB并检索它们。

或者为什么不储存要播放的文件引用?

2

一般来说,最好不要二进制文件存储在任何数据库。您最好将该文件作为文件写入磁盘,然后将路径存储在数据库中。

1

这并不总是最好的存储磁盘上的文件。看看这个比较:

http://www.sqlite.org/intern-v-extern-blob.html

下面是一个使用Ruby和续集宝石它,我该怎么办:

创建使用该架构的一个表。该文件是一个blob,sha是该文件的名称。在这种情况下,我所有的文件都是可变比特率的单声道mp3文件,大小为2K-3K。 db中有大约40 000个文件。我使用sha1值作为文件名,因为我有很多条目具有相同的声音,所以我节省了一些空间。

CREATE TABLE `sound` (`id` integer PRIMARY KEY AUTOINCREMENT, `sha` text, `file` blob); CREATE INDEX `sound_sha_index` ON `sound` (`sha`); 

使用Ruby可以创建数据库这样的:

db = Sequel.sqlite('./sound.db')  
db.create_table :sound do 
    primary_key :id, :index => true 
    column :sha, :text, :index => true 
    column :file, :blob 
end 

将文件加载到数据库中。假设你有一个名为“声音”目录中的文件,这里是如何:

DB = Sequel.sqlite('./sound.db') 
files = Dir['./sound/*.mp3'] 
files.each_with_index do |f, i| 
    # progress 
    print "\r #{((i.to_f/files.size)*100).round(2)}%" 
    # get the file name without directory and extension 
    f =~ /\/sound\/(.+)\.mp3/ 
    # insert into db 
    DB[:sound].insert :sha => $1, :file => File.read("#{f}").to_sequel_blob 
end 

播放声音的iPhone应用程序。将sound.db文件复制到iPhone项目中。这是我正在使用的代码。它基于FMDB和AVAudioPlayer。

SoundPlayer.h

#import <Foundation/Foundation.h> 
#import <AVFoundation/AVFoundation.h> 
#import "FMDatabase.h" 
#import "FMDatabaseQueue.h" 

@interface SoundPlayer : NSObject 
{ 
    FMDatabaseQueue *db; 
} 

@property (nonatomic, retain) AVAudioPlayer *audioPlayer; 

- (void)play:(NSString *)sha; 
- (void)free; 
@end 

SoundPlayer.m

#import "SoundPlayer.h" 
#import "DictAppDelegate.h" 

@implementation SoundPlayer 

- (SoundPlayer*)init 
{ 
    NSString *dbPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"sound.db"]; 
    db = [FMDatabaseQueue databaseQueueWithPath: dbPath]; 

    return self; 
} 

- (void)play:(NSString *)sha 
{ 
    [db inDatabase:^(FMDatabase *connection) { 
     // Execute and fetch result 
     NSString *query = [NSString stringWithFormat:@"select file from sound where sha = '%@' limit 1", sha]; 

     FMResultSet *rs = [connection executeQuery:query]; 

     while([rs next]) { 

      NSData *file = [rs dataForColumn: @"file"]; 

      NSError *error; 

      self.audioPlayer = [[AVAudioPlayer alloc] initWithData: file error:&error]; 
      self.audioPlayer.numberOfLoops = 0; 
      self.audioPlayer.volume = 1.0f; 
      [self.audioPlayer prepareToPlay]; 

      if (self.audioPlayer == nil) { 
       NSLog(@"Error playing sound: %@", [error description]); 
      } else { 
       [self.audioPlayer play]; 
      } 
     } 
    }]; 
} 

// Cleanup 
- (void)free { 
    [db close]; 
} 

@end 

使用从某个文件在你的代码是这样的:

self.soundPlayer = [[SoundPlayer alloc] init]; 
[self.soundPlayer play:[entry valueForKey:@"sha"]]; 

其中[进入valueForKey:@“沙“]]返回一个NSString,它是我存储在另一个条目表中的文件名。

+0

嘿..很好地描述。你能告诉我你在哪里写红宝石代码? db = Sequel.sqlite('./ sound.db') db.create_table:sound do primary_key:id,:index => true column:sha,:text,:index => true column:file ,:blob end` – 2016-03-03 11:38:24