'분류 전체보기'에 해당되는 글 109건
- 2010.11.11
- 2010.11.09
- 2010.11.08
- 2010.11.02
- 2010.11.01
- 2010.11.01
- 2010.10.25
- 2010.10.01
- 2010.09.05
- 2010.07.06
전국 맛집... (0) | 2010.11.11 |
---|---|
[우유의 진실] 오래 살고 싶으면 우유 절대로 마시지 마라 (0) | 2009.09.20 |
사랑니때문에 정말 앞니들이 틀어지는걸까? (0) | 2009.06.18 |
xml 노드에 이미지 URL 이 있을 경우 비동기식으로 이미지 처리하는것.
UITables with Downloaded Images – Easy Asynchronous Code
http://www.markj.net/iphone-asynchronous-table-image/
Readers… do look through the comments if you plan to use this code, other people have posted improvements. Thanks for all the great feedback everyone. MJ
The app ‘Postcards’ from my iPhone developer training class is a utility app for quickly sending a customized postcard, and one thing that makes it super easy is that you can grab pictures from Flickr to include in the postcard design. Postcards makes simple HTTP calls Flickr’s REST API to download public domain images and displays them in a UITableView for the user to pick from. Cocoa Touch makes this all simple and easy to code, and my first development version used synchronous calls to get the images by using NSData dataWithContentsOfURL:
.
.
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urls]];
Making synchronous calls to remote web servers from the thread that’s running the apps GUI is of course a bad idea that results in a laggy UI and unsatisfied users. Using synchronous calls in UITableView cellForRowAtIndexPath to load all the images results in a problem six times worse (for 6 rows on the screen) and makes scrolling basically broken as the table won’t scroll until it has the next cell, which it can’t get while the app is waiting for an image to download. Then imagine that on the Edge network! Obviously we need something multi-threaded that can load the images in parallel in the background and update the UI as they finish downloading.
Multi-threaded programming is hard and should be avoided whenever possible, and in this case Cocoa’s beautiful design came to my rescue:
UIView heirachy + URL loading system + delegate design = multi-threaded image loading with no multi-threaded coding!
How can you have your cake and eat it too? Every iPhone app is a multi-threaded program, or at least its running in conjuction with the multi-threaded iPhone operating system. Use the right delegate methods in the right ways, and you can take advantage of extra threads of execution that the iPhone gives you for free without writting any multi-threaded code of your own, hence sidesteping the problem of threading bugs in your code. An iPhone app is one big event loop – your classes have methods that the event loop calls in response to stuff happening on the device and in your app. When you use the URL loading system’s asynchronous APIs, the iPhone uses a different thread than the one running your app’s event loop to load the contents of the URL, and it makes callbacks via your apps event loop when data has been downloaded.
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; - (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)incrementalData
Note carefully, when data has arrived from the remote webserver, that other iPhone thread doing the downloading doesn’t make calls into your objects at the same time as your methods are running, it puts messages into your apps event loop. If it called your app directly then chances are your app would be running some UI code or something and you’d have to write thread safe code. Instead, the call that data is ready arrives as an event on the event loop. Events on the event loop run single threaded, one at a time. Using this we can get asynchrous image download from Flickr without writting thread safe code ourselves. Even better, Cocoa’s URL loading system will download those URLs in parallel! For free!
That’s all well and good, but how do you get a table view to update the UITableViewCell with the image after its already been returned? A UIImage is imutable (right?) so you can’t change its image later when the image data has downloaded. Turns out Apple made this super easy too. Instead of putting a UIImage in the UITableViewCell, you put your own UIView object, that is sized correctly for the image you want to display, into the content view of the UITableCell (as a subview). At first your view object it can be empty, or it can have a dummy image in it, or you can pop in one of those spinny ’something is happening’ views. Then when the image data is downloaded, create a UIImageView with the image and pop it in your view in the cell. Hey presto… it appears. While all this is happening the user can be scrolling and going back and forth with a fully functioning UI.
I put this all together in a class AsyncImageView, listed below. It’s use is simple
LoadImageFromURL will return right away, the image will load in the background, and will automatically appear in the view when its finished downloading. The code posted below is something I whipped up pretty quickly (and I didn’t leak check yet!), but hey – parallel, asynchronous image download and display in about 40 lines of code with no thread-safe worries? Works in smooth scrolling tables, even on the Edge network? I rate it a big win, and wanted to share the technique.
I’ve developed an iPhone programming training class that I will be teaching soon in the SFBay Area (though my partners and I could probably bring it to you). It’s very hands on, and specially designed to help professional programmers new to Cocoa and Objective-C over the difficult initial learning curve. In the class we build the Postcards app from start to finish, including AsyncImageView. Email me for more info: markj at markj.net
@interface AsyncImageView : UIView { NSURLConnection* connection; NSMutableData* data; } @end @implementation AsyncImageView - (void)loadImageFromURL:(NSURL*)url { if (connection!=nil) { [connection release]; } if (data!=nil) { [data release]; } NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0]; connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; //TODO error handling, what if connection is nil? } - (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)incrementalData { if (data==nil) { data = [[NSMutableData alloc] initWithCapacity:2048]; } [data appendData:incrementalData]; } - (void)connectionDidFinishLoading:(NSURLConnection*)theConnection { [connection release]; connection=nil; if ([[self subviews] count]>0) { [[[self subviews] objectAtIndex:0] removeFromSuperview]; } UIImageView* imageView = [[[UIImageView alloc] initWithImage:[UIImage imageWithData:data]] autorelease]; imageView.contentMode = UIViewContentModeScaleAspectFit; imageView.autoresizingMask = ( UIViewAutoresizingFlexibleWidth || UIViewAutoresizingFlexibleHeight ); [self addSubview:imageView]; imageView.frame = self.bounds; [imageView setNeedsLayout]; [self setNeedsLayout]; [data release]; data=nil; } - (UIImage*) image { UIImageView* iv = [[self subviews] objectAtIndex:0]; return [iv image]; } - (void)dealloc { [connection cancel]; [connection release]; [data release]; [super dealloc]; } @end
And here is the usage in UITableViewCell. The AsyncImageView gets tagged with 999, and when it gets recycled, that 999 tagged view gets fished out and removed. So only the cell is being recycled, not the AsyncImageView object. When its removed from the cells content view it also gets released, causing dealloc, which in turn cancels the url download (if its outstanding).
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"ImageCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; } else { AsyncImageView* oldImage = (AsyncImageView*) [cell.contentView viewWithTag:999]; [oldImage removeFromSuperview]; } CGRect frame; frame.size.width=75; frame.size.height=75; frame.origin.x=0; frame.origin.y=0; AsyncImageView* asyncImage = [[[AsyncImageView alloc] initWithFrame:frame] autorelease]; asyncImage.tag = 999; NSURL* url = [imageDownload thumbnailURLAtIndex:indexPath.row]; [asyncImage loadImageFromURL:url]; [cell.contentView addSubview:asyncImage]; return cell; }
윈도우에서 Objective-C 개발환경 설정하기 3 (실제 예제실행하기) (0) | 2010.11.19 |
---|---|
윈도우에서 Objective-C 개발환경 설정하기 2 (Dev-Cpp 사용) (0) | 2010.11.19 |
윈도우에서 Objective-C 개발환경 설정하기 1 (환경설정) (0) | 2010.11.01 |
i. live 2.0 지상파 DMB/ 케이블TV 보기 (0) | 2010.10.01 |
원격으로 PC 접속 (0) | 2010.07.05 |
3. GNUstep System 설치3-완료
4. GNUstep Core 설치1-역시 계속 next
6. GNUstep Core 설치3- 완료
8.Dev-C++ 설치 두번째.. -뭐가있는 지 살펴볼려다가 역시 귀차니즘.. 다음~
9.Dev-C++ 설치 세번째.. -완료
윈도우에서 Objective-C 개발환경 설정하기 2 (Dev-Cpp 사용) (0) | 2010.11.19 |
---|---|
비동기식 이미지 로딩 (0) | 2010.11.02 |
i. live 2.0 지상파 DMB/ 케이블TV 보기 (0) | 2010.10.01 |
원격으로 PC 접속 (0) | 2010.07.05 |
XCode 블럭(괄호) 스타일 바꾸기 (0) | 2010.06.17 |
http://forum.qnap.com/viewtopic.php?f=178&t=30278
http://wiki.birth-online.de/know-how/hardware/apple-iphone/airvideo-server-linux
http://forum.qnap.com/viewtopic.php?f=177&t=32731&p=148116&hilit=air+video#p148116
http://www.inmethod.com/forum/posts/list/450/34.page#12890
퍼온글입니다...
http://cafe.naver.com/synologynas/5449
꼭 DS210j가 아니라 ARMv5 CPU를 사용하는 NAS에 해당하는 글이겠군요.
위키에서 찾아보니 DS210j와 같은 CPU를 사용하는 모델은 다음과 같습니다.
x10 Series : DS110j, DS210j, DS410j
x09 Series : DS109, DS209, DS409, DS409Slim, RS409
Air Video Server 를 설치하기 전에 먼저 Bootstrap을 설치해 주셔야 합니다.
이것은 생략하겠습니다.
자세한 설명은 제일 아래 참고 사이트에 들어가시면 보실 수 있습니다.
댓글도 읽어보시면 많은 도움이 됩니다.
퍼가실 때는 출처를 적어주시기 바랍니다.
지금부터 시작하겠습니다.
--------
제가 작업한 환경 그대로 적겠습니다.
작업 디렉토리는 임의로 바꾸셔도 됩니다.
0. 설치 환경
접속 방법 : ssh
유저 : root
작업디렉토리 : /opt/etc
Air Video Server 설치 디렉토리 : /opt/air_video
Java 설치 디렉토리 /opt/java
/etc/profile에 아래 내용을 추가하거나 수정합니다.
수정 후에는 로그오프하고 로그온 하시거나 .(점) /etc/profile 명령어를 실행합니다.
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/syno/bin:/usr/syno/sbin:/opt/bin:/opt/sbin:/opt/java/bin:/opt/arm-none-linux-gnueabi/bin
LD_LIBRARY_PATH=/opt/lib:/lib:/opt/arm-none-linux-gnueabi/lib
LD_RUN_PATH=/opt/lib:/lib:/opt/arm-none-linux-gnueabi/lib
JAVA_HOME=/opt/java
export PATH LD_LIBRARY_PATH LD_RUN_PATH JAVA_HOME
LANG="ko_KR.UTF-8"
LC_ALL="ko_KR.UTF-8"
SUPPORTED="ko_KR.UTF-8:ko_KR:ko"
export LANG LC_ALL SUPPORTED
1. 패키지 설치
다행히도 대부분은 패키지 형태로 설치가 가능합니다.
ipkg install optware-devel
ipkg install gcc
ipkg install git
ipkg install grep
ipkg install sdl
ipkg install sdl-dev
ipkg install libmpeg2
ipkg install mpeg2dec
ipkg install libpth
ipkg install lame
ipkg install faad2
ipkg install xvid
ipkg install libjpeg
ipkg install vim
ln -s /opt/bin/bash /bin/bash
여기까지는 아주 쉽게 설치가 진행됩니다.
2. faac 설치
wget http://switch.dl.sourceforge.net/sourceforge/faac/faac-1.28.tar.gz
tar -xzf faac-1.28.tar.gz
cd faac-1.28
./configure --prefix=/opt --without-mp4v2
make
make install
이것도 별 문제없이 설치가 됩니다.
3. x264 설치
ipkg의 패키지가 구버전이라서 최신 버전으로 다운받아 설치해야 합니다.
패키지가 업데이트되면 이 과정이 1번으로 이동하겠군요.
git clone git://git.videolan.org/x264.git
cd /opt/etc/x264
./configure --prefix=/opt --disable-asm
make
make install
4. Library 링크 설정
cd /opt/lib
rm libxvidcore.so
ln -s libxvidcore.so.4.2 libxvidcore.so
ln -s libxvidcore.so.4.2 libxvidcore.so.4
ln -s libx264.so.106 libx264.so
일부 라이브러리의 링크가 제대로 안되어 있어 링크를 설정해 줍니다.
5. mp4creator 설치
이것 때문에 무지 많이 고생을 했습니다.
완벽한 컴파일이 안되고 에러가 납니다만 필요한 파일은 얻을 수 있습니다.
http://sourceforge.net/projects/mpeg4ip/ 접속하여 소스 다운
==> 이것은 wget으로 받아지지 않더군요.
tar -xzf mpeg4ip-1.5.0.1.tar.gz
cd mpeg4ip-1.5.0.1
소스코드를 조금 손봐야 하는데 vi에디터 기준으로 설명합니다.
적당한 에디터로 아래와 같이 수정하시면 됩니다.
vim +1733 lib/rtp/rtp.c
i를 누르고 아래와 같이 세 줄 앞에 // 로 주석처리해줍니다.
//if (((packet->common.count * 6) + 1) < (ntohs(packet->common.length) - 5)) {
// rtp_message(LOG_NOTICE, "Profile specific SR extension ignored");
//}
ESC키를 누르고 :wq 엔터 눌러 저장하고 종료합니다.
vim +1752 lib/rtp/rtp.c
여기도 마찬가지로 i를 누르고 세 줄 앞에 // 로 주석처리해 줍니다.
//if (((packet->common.count * 6) + 1) < ntohs(packet->common.length)) {
// rtp_message(LOG_INFO, "Profile specific RR extension ignored");
//}
ESC키를 누르고 :wq 엔터 눌러 저장하고 종료합니다.
./bootstrap --prefix=/opt --disable-mp4live --disable-mp4live-alsa
make ==> ERROR 발생하지만 무시합니다.
cd lib
make install ==> ERROR 발생하지만 무시합니다.
cd ../server
make install
6. ffmpeg-for-2.2.5 설치
wget http://www.inmethod.com/air-video/download/ffmpeg-for-2.2.5.tar.bz2
tar jxf ffmpeg-for-2.2.5.tar.bz2
./configure --prefix=/opt --enable-static --disable-shared --enable-gpl \
--enable-nonfree --enable-libfaac --enable-libfaad --enable-libfaadbin \
--enable-libmp3lame --enable-libx264 --enable-libxvid --disable-asm \
--disable-decoder=aac
make
make install
7. Java 설치
ARMv5용 Java SE를 다운받아 설치해야 합니다.
다운받기 위해서는 몇 가지 정보를 입력해야 합니다. (이름, 이메일주소 등)
Java SE for Embedded evaluation downloads page:
http://java.sun.com/javase/downloads/embedded.jsp
아래 파일을 다운받으시면 됩니다.
ejre-1_6_0_10-fcs-b42-linux-armv5-sflt-eabi-headless-10_jun_2010.tar.gz
cd /opt
tar xfz ejre-1_6_0_10-fcs-b42-linux-armv5-sflt-eabi-headless-10_jun_2010.tar.gz
ln -s ejre1.6.0_10 java
8. Air Video Server 설치
md /opt/air_video
cd /opt/air_video
아래 URL에 접속하시면 최신의 파일을 다운받으실 수 있습니다.
http://inmethod.com/forum/posts/list/1856.page
지금 현재(2010-10-09) 가장 최신의 리눅스용 파일의 버전은 alpha4 입니다.
wget http://inmethod.com/air-video/download/linux/alpha4/AirVideoServerLinux.jar
9. 글꼴 설치 및 한글 글꼴 변경
ipkg install ttf-bitstream-vera
ipkg install fontconfig
글꼴파일 다운 :
위 글꼴은 첨부하였습니다.
FTP를 이용해서 한글 글꼴 파일 업로드 : /share/MD0_DATA/.qpkg/JRE/jre/lib/fonts
폰트파일 복사후에 fonts.dir 파일을 수정해야 한다.( JRE 설치된 폴더에... )
fonts.dir 파일 맨 하단에 추가한 폰트파일에 대한 내용추가 : batang.ttc -ms-batang-medium-r-normal--0-0-0-0-c-0-ksc5601.1987-0
fonts.dir 파일 저장 후 chmod 444 fonts.dir 명령으로 속성 복원
참고_ http://www.myhyun.com/5881
http://confluence.goldpitcher.co.kr/pages/viewpage.action?pageId=96075806
10. Air Video 설정파일 만들기(한글자막 설정)
vi /opt/air_video/test.properties
path.ffmpeg = /opt/bin/ffmpeg
path.faac = /opt/bin/faac
path.mp4creator = /opt/bin/mp4creator
password =
subtitles.encoding = UTF-8
subtitles.font = Bitstream Vera Sans Mono
folders = Movie:/volume1/movie,Video:/volume1/video (제목:경로,제목:경로,...)
10. Air Video Server 구동하기
/opt/java/bin/java -jar /opt/air_video/AirVideoServerLinux.jar /opt/air_video/test.properties
-jar 빼먹지 마세요.
[/opt/etc/airvideo] # cat Readme.txt
cd /share/MD0_DATA/.qpkg/JRE/jre/bin
java -jar /opt/etc/airvideo/AirVideoServerLinux.jar /opt/etc/airvideo/test.properties
[/opt/etc/airvideo] # java -jar /opt/etc/airvideo/AirVideoServerLinux.jar /opt/etc/airvideo/test.properties
11. 참고 자료
우분투에서 에어비디오 서버 구동하기
http://clien.career.co.kr/cs2/bbs/board.php?bo_table=lecture&wr_id=64177&page=0
Video-Streaming from QNAP NAS via AirVideo to iPad or iPhone
http://forum.qnap.com/viewtopic.php?f=177&t=32731
AirVideo Server under Linux
http://wiki.birth-online.de/know-how/hardware/apple-iphone/airvideo-server-linux
12. 한글 자막 인코딩 시 유의사항
자막파일 (.srt 또는 .smi) 은 UTF-8로 인코딩 되어 있어야 합니다.
가장 쉬운 방법은 다음과 같습니다.
1. 메모장에서 자막파일을 읽은 후
2. 다른 이름으로 저장
3. 인코딩을 ANSI에서 UTF-8로 변경
4. 파일 형식을 모든 파일로 변경
5. 저장
[TS-509 PRO] 어플리케이션 자동 실행방법 (0) | 2011.03.17 |
---|---|
TS-509 Pro 개봉기 (0) | 2009.10.18 |
[HDD] QNAP TS-509 PRO 에 사용중인 하드 (0) | 2009.10.14 |
NAS 구축하기 (0) | 2009.08.10 |
어플을 설치하지 않고, 사파리에서 TV 보기
아이폰 사파리에서 주소창에 http://ev7.net/ 를 입력
시청 가능 공중파 채널 : MBC, SBS, KBS 2TV, KBS24NEWS HD, EBSi, ESB+1, ESB+2, OBS, GTB,
시청 가능 케이블 채널 : MNET, KMTV, SCIENCE, YHNEWS, KCTV, KCTVN, MapoITV, MBN, MTN, WOWTV ....... 등등
이외에도, 종교채널과 NHK 도 시청 가능.
i라이브와 트랜드는 TV 모음 사이트. 지원하는 사이트는 공중파, 케이블, 종교방송등 많다. MBC와 SBS는 저작권 문제로 단추가 비활성화되어 있다. 비활성화된 단추는 몇초 정도 누르고 있으면 시청 가능.
키스코는 스트리밍 서비스만 되는듯. 다만 아이폰 사이트에서 생방송을 제공하며,
생방송을 이용하면 KBS 2 TV를 시청할 수 있고. 방송은 랜덤으로 나오는듯.
i비디오는 TV 사이트는 아니다. 미드나 일드 위주...회원가입했으나.. 로그인하면 로그인 성공했다고 나오지만...로그인이 되지 않는듯 하다..그래서 볼수가 없다....ㅋ
비동기식 이미지 로딩 (0) | 2010.11.02 |
---|---|
윈도우에서 Objective-C 개발환경 설정하기 1 (환경설정) (0) | 2010.11.01 |
원격으로 PC 접속 (0) | 2010.07.05 |
XCode 블럭(괄호) 스타일 바꾸기 (0) | 2010.06.17 |
애플 추천 어플 (0) | 2010.05.05 |
마우스 우클릭 금지 해제하기 (0) | 2010.03.31 |
---|---|
윈도우 프로세스에 실행되고 파일 정보 검색 (0) | 2010.03.14 |
[윈도7] 내 PC 가 가상화를 지원하는지 여부 확인하기 (0) | 2010.01.05 |
칩스엔태크 트래샌드 32G 메모리 인식 오류 (0) | 2009.11.02 |
[노턴 고스트] 노턴 고스트 14 한글판 (0) | 2009.10.11 |
[에어컨] 에어컨 관리 (0) | 2010.06.11 |
---|---|
[자동차] 한국인이 디자인한 자동차들 (0) | 2010.06.07 |
[삼성] 삼성화재 개새끼들... (0) | 2010.06.07 |
자동차 보험회사가 알려주기 싫어하는 9가지 비밀 (0) | 2009.06.24 |