2009-06-29 5 views

답변

4

왜 SQL 데이터베이스에 오디오 파일을 저장하려고하는지 모르지만 sqlite3은 BLOB를 지원합니다. 따라서 BLOB으로 저장하고 검색하십시오.

또는 재생할 파일에 대한 참조를 저장하지 않는 이유는 무엇입니까?

2

일반적으로 모든 데이터베이스에 바이너리 파일을 저장하지 않는 것이 가장 좋습니다. 이 파일을 디스크에 파일로 작성한 다음 데이터베이스에 저장하는 것이 좋습니다.

1

디스크에 파일을 저장하는 것이 항상 최선의 방법은 아닙니다. 이 비교에서보세요 :

이 스키마를 사용하여 테이블을 만듭니다

여기

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

가 나는 그것이 루비와 속편 보석을 사용하여이 작업을 수행하는 방법이다. 파일은 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`); 

이 같은 DB를 생성 할 수 있습니다 루비를 사용 :

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 : 소리 수행 primary_key : id, : index => true 열 : sha, : 텍스트, : 인덱스 => true 열 : 파일 , : blob end' –

+0

루비 코드를 실행하면 오류가 표시됩니까? ? '정의되지 않은 메소드 to_sequel_blob for # ' –

관련 문제