2012年10月5日 星期五

Download Youtube Video (2012 09)

Since fucking Google/Youtube change the get_video_info again, it add a new parameter "signature", and it cause the old method not work anymore,

now here is the solution.


package vimeok.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;

import android.util.Log;


public class VideoParser {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

List<VideoInfoObj> videoList= getVideoList("jd2-Nf86jvA");
for(VideoInfoObj vo: videoList){

System.err.println(vo.getVideoType());
System.err.println(vo.getDwName());
System.err.println(vo.getUrl());

File f=new File(vo.getDwName());
       try {
org.apache.commons.io.FileUtils.copyURLToFile(new URL(vo.getUrl()),f);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}
public static List<VideoInfoObj> getVideoList(String vid){
String[] fmt_str = new String[103];
fmt_str[0]  = "(FLV, 320 x 240, Mono 22KHz MP3)"; // delete ?
fmt_str[5]  = "(FLV, 400 x 240, Mono 44KHz MP3)";
fmt_str[6]  = "(FLV, 480 x 360, Mono 44KHz MP3)"; // delete ?
fmt_str[34] = "(FLV, 640 x 360, Stereo 44KHz AAC)";
fmt_str[35] = "(FLV, 854 x 480, Stereo 44KHz AAC)";

fmt_str[13] = "(3GP, 176 x 144, Stereo 8KHz)";    // delete ?
fmt_str[17] = "(3GP, 176 x 144, Stereo 44KHz AAC)";
fmt_str[36] = "(3GP, 320 x 240, Stereo 44KHz AAC)";

fmt_str[18] = "(MP4(H.264), 640 x 360, Stereo 44KHz AAC)";
fmt_str[22] = "(MP4(H.264), 1280 x 720, Stereo 44KHz AAC)";
fmt_str[37] = "(MP4(H.264), 1920 x 1080, Stereo 44KHz AAC)";
fmt_str[38] = "(MP4(H.264), 4096 x 3072, Stereo 44KHz AAC)";
fmt_str[83] = "(MP4(H.264), 854 x 240, Stereo 44KHz AAC)";
fmt_str[82] = "(MP4(H.264), 640 x 360, Stereo 44KHz AAC)";
fmt_str[85] = "(MP4(H.264), 1920 x 520, Stereo 44KHz AAC)";
fmt_str[84] = "(MP4(H.264), 1280 x 720, Stereo 44KHz AAC)";

fmt_str[43] = "(WebM(VP8), 640 x 360, Stereo 44KHz Vorbis)";
fmt_str[44] = "(WebM(VP8), 854 x 480, Stereo 44KHz Vorbis)";
fmt_str[45] = "(WebM(VP8), 1280 x 720, Stereo 44KHz Vorbis)";
fmt_str[100] = "(WebM(VP8), 640 x 360, Stereo 44KHz Vorbis)";
fmt_str[101] = "(WebM(VP8), 854 x 480, Stereo 44KHz Vorbis)";
fmt_str[46] = "(WebM(VP8), 1920 x 540, Stereo 44KHz Vorbis)";
fmt_str[102] = "(WebM(VP8), 1280 x 720, Stereo 44KHz Vorbis)";

String[] ft_str = new String[103];
ft_str[0]  = "flv";//"(FLV, 320 x 240, Mono 22KHz MP3)";
ft_str[5]  = "flv";//"(FLV, 400 x 240, Mono 44KHz MP3)";
ft_str[6]  = "flv";//"(FLV, 480 x 360, Mono 44KHz MP3)";
ft_str[34] = "flv";//"(FLV, 640 x 360, Stereo 44KHz AAC)";
ft_str[35] = "flv";//"(FLV, 854 x 480, Stereo 44KHz AAC)";

ft_str[13] = "3gp";//"(3GP, 176 x 144, Stereo 8KHz)";    // delete ?
ft_str[17] = "3gp";//"(3GP, 176 x 144, Stereo 44KHz AAC)";
ft_str[36] = "3gp";//"(3GP, 320 x 240, Stereo 44KHz AAC)";

ft_str[18] = "mp4";//"(MP4(H.264), 640 x 360, Stereo 44KHz AAC)";
ft_str[22] = "mp4";//"(MP4(H.264), 1280 x 720, Stereo 44KHz AAC)";
ft_str[37] = "mp4";//"(MP4(H.264), 1920 x 1080, Stereo 44KHz AAC)";
ft_str[38] = "mp4";//"(MP4(H.264), 4096 x 3072, Stereo 44KHz AAC)";
ft_str[83] = "mp4";//"(MP4(H.264), 854 x 240, Stereo 44KHz AAC)";
ft_str[82] = "mp4";//"(MP4(H.264), 640 x 360, Stereo 44KHz AAC)";
ft_str[85] = "mp4";//"(MP4(H.264), 1920 x 520, Stereo 44KHz AAC)";
ft_str[84] = "mp4";//"(MP4(H.264), 1280 x 720, Stereo 44KHz AAC)";

ft_str[43] = "webm";//"(WebM(VP8), 640 x 360, Stereo 44KHz Vorbis)";
ft_str[44] = "webm";//"(WebM(VP8), 854 x 480, Stereo 44KHz Vorbis)";
ft_str[45] = "webm";//"(WebM(VP8), 1280 x 720, Stereo 44KHz Vorbis)";
ft_str[100] = "webm";//"(WebM(VP8), 640 x 360, Stereo 44KHz Vorbis)";
ft_str[101] = "webm";//"(WebM(VP8), 854 x 480, Stereo 44KHz Vorbis)";
ft_str[46] = "webm";//"(WebM(VP8), 1920 x 540, Stereo 44KHz Vorbis)";
ft_str[102] = "webm";//"(WebM(VP8), 1280 x 720, Stereo 44KHz Vorbis)";

List<VideoInfoObj> list=new ArrayList<VideoInfoObj>();
try{
int succ = 0;
//String vid="jd2-Nf86jvA";
String url="http://www.youtube.com/get_video_info?video_id="+vid;//+"&eurl=http://10.1.2.104";
//String rdata= org.apache.commons.io.FileUtils.readFileToString(new File("d:\\get_video_info.php"));
String rdata=getMessageFromUrl(url);
Log.w("***************************",rdata);
URLDecoder dec = new URLDecoder();
//String tmp_result = java.net.URLDecoder.decode(content, "UTF-8");
String[] rdataArray = rdata.split("&");

for(int i=0; i< rdataArray.length; i++){
if(rdataArray[i].length()>26){
String r0 = rdataArray[i].substring(0, 26);
if(r0.equals("url_encoded_fmt_stream_map")){
     String r1 = dec.decode(rdataArray[i].substring(27),"UTF-8");
     String[] temp1 = r1.split(",");
     ArrayList<Integer> fmt = new ArrayList<Integer>();
     ArrayList fmt_url = new ArrayList();
     ArrayList fmt_sig = new ArrayList();
     for(int j = 0; j < temp1.length; j++){
     String[] temp2 = temp1[j].split("&");
     for(int jj = 0; jj < temp2.length; jj++){
     Integer temp_itag = -1;
             String temp_type = "";
             System.err.println(temp2[jj]);
             if(temp2[jj].substring(0, 5).equals("itag=")){
               temp_itag = new Integer(Integer.parseInt(temp2[jj].substring(5), 10));
               fmt.add(temp_itag);
             }else if(temp2[jj].substring(0, 4).equals("url=")){
               fmt_url.add(temp2[jj].substring(4));
             }else if(temp2[jj].substring(0, 4).equals("sig=")){
               fmt_sig.add(temp2[jj].substring(4));
             }else if(temp2[jj].substring(0, 5).equals("type=")){
               temp_type = '(' + dec.decode(temp2[jj].substring(5),"UTF-8") + ')';
             }
             System.err.println("temp_itag="+temp_itag);
             System.err.println(fmt_str[44]);
             if(temp_itag>-1){
             if(fmt_str[temp_itag].equals("undefined")){
               fmt_str[temp_itag] = temp_type;
             }
             }
         }
     }
     String dllinks = "";
     String webmlinks = "";
     System.err.println("fmt.size()="+fmt.size());
     for(int k=0; k< fmt.size(); k++){
     System.err.println(k);
       if(fmt.get(k) == 43 || fmt.get(k) == 44 || fmt.get(k) == 45 || fmt.get(k) == 46 || fmt.get(k) == 100 || fmt.get(k) == 101 || fmt.get(k) == 102){
//          if(webmlinks.length() > 0){
//            webmlinks += "<br />";
//          }        
         //webmlinks += "<a href=" + dec.decode(fmt_url.get(k).toString(),"UTF-8") + "&signature=" + fmt_sig.get(k) + " target=_blank><b>Watch online&nbsp;&nbsp;&nbsp;" + fmt_str[fmt.get(k)]+ "</b></a>";
         //System.err.println("webmlinks="+webmlinks);
       }else{
//          if(dllinks.length() > 0){
//            dllinks += "<br />";
//          }
        // dllinks += "<a href=" + dec.decode(fmt_url.get(k).toString(),"UTF-8") + "&signature=" + fmt_sig.get(k) + " target=_blank><b>Download&nbsp;&nbsp;&nbsp;" + fmt_str[fmt.get(k)] + "</b></a>";
        Log.w("***************",dec.decode(fmt_url.get(k).toString(),"UTF-8") + "&signature=" + fmt_sig.get(k));
        //I just need mp4 file
         if(fmt.get(k) ==18 ||fmt.get(k) ==22 ||fmt.get(k) ==37 ||fmt.get(k) ==38 ||fmt.get(k) ==82 ||fmt.get(k) ==83  ||fmt.get(k) ==84  ||fmt.get(k) ==85 ){
         String dl=dec.decode(fmt_url.get(k).toString(),"UTF-8") + "&signature=" + fmt_sig.get(k);
         String fileName="d:\\video"+System.currentTimeMillis()+"."+ft_str[fmt.get(k)];
//          File f=new File(fileName);
//          org.apache.commons.io.FileUtils.copyURLToFile(new URL(dl),f);
//          System.err.println("dllinks="+dl);
         VideoInfoObj vi= new VideoInfoObj();
         vi.setDwName(fileName);
         vi.setUrl(dl);
         vi.setVideoType(fmt_str[fmt.get(k)]);
         list.add(vi);
         }
       }
     }
     System.err.println(r1);
}
//System.err.println(r0);
}
}


}catch(Exception e){
e.printStackTrace();
}
return list;
}
public static String getMessageFromUrl(String msgUrl) throws IOException {
URL url = new URL(msgUrl);
BufferedReader in = new BufferedReader(new InputStreamReader(
url.openStream()));
String inputLine;
StringBuffer sb = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
sb.append(inputLine);
}
in.close();
return sb.toString();
}

}

public class VideoInfoObj{
private String url="";
private String dwName="";
private String videoType="";
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getDwName() {
return dwName;
}
public void setDwName(String dwName) {
this.dwName = dwName;
}
public String getVideoType() {
return videoType;
}
public void setVideoType(String videoType) {
this.videoType = videoType;
}
}

2012年8月7日 星期二

修改過 Mobclix 的結果.


經過調整 Mobclix 裡的廣告商後, 果然馬上就有點效果, 雖然離高峰時每天超過100美金的還差很多, 再繼續努力吧.



DayTotal Earnings

2012年8月4日 星期六

調整 Mobclix

剛剛調整了一下 Mobclix 的廣告, 把一些收入太低/無效的廣告商去掉, 
只留下了
AdTini
inmobi
mdotm
mojiva
saymedia
smatto


Mdotm     21,589 $0.51 283 1.31% $0.04 $10.97
Smaato       2,583         $1.92 12 0.47% $0.41 $4.96
Mojiva       7,933 $0.33 84 1.06% $0.03 $2.60
AdTini     29,634 $0.40 200 0.68% $0.06 $11.83
Jumptap       1,339 $0.31 12 0.90% $0.03 $0.42
InMobi       2,618 $0.15 25 0.96% $0.02 $0.39
Zestadz          333  $0.45 6 1.80% $0.03 $0.15
Tapsense     2,085         $0.04 8 0.38% $0.01 $0.08
Lifestreet  524          $0.13 25 4.77% $0.00 $0.07
Saymedia  129          $0.37 0 0.00% $0.00 $0.05
Yoc                    34          $0.53 1 2.94% $0.02 $0.02
AdTiniplus      3          $3.27 0 0.00% $0.00 $0.01
AdFonic          452          $0.00 3 0.66% $0.00 $0.00
Radium              12 $0.00 0 0.00% $0.00 $0.00
Vdopia              7          $0.00 0 0.00% $0.00 $0.00

再觀察一星期再做調整

2012年7月27日 星期五

How to play sound file in Objective C


NSString *newAudioFile = [[NSBundle mainBundle] pathForResource:@"t5"  ofType:@"wav"];
    NSError *error;
    
    AVAudioPlayer  player=  [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:newAudioFile] error:&error];
    
    [player setDelegate:self];
    
    [player prepareToPlay];
    
    [player play];

2012年7月25日 星期三

LeadBolt mobile advertising

Recently I try to use this mobile advertising networks, good CPM.

it provide banner ad, ad wall, notification ad, short ad in one sdk.

but it just work on English language country/area.

http://leadbolt.com/developers_signup.php?ref=10027093

Android app --- Call to SpongeBob

My First Semi-Game app "Call to SpongeBob"


It turn your mobile phone into a child's toy phone, they can use this app to call SpongeBob, Patrick, Squidward, Krabs, Plankton and Sandy.

Like a toy phone, it provide beautiful key tone for your children,
Piano tones, and amazing Bird tones.

* this is just a game, don't worry, it will not make a real phone call.


https://play.google.com/store/apps/details?id=com.vimeok.spongebob






new app released (Asian boy's pop bands MV collection)


https://play.google.com/store/apps/details?id=vimeok.mediaapp.musictv.m




Top 20 Asian/Korean Boy pop-band music video collection, including--
SHINee,
Super Junior,
2AM,
Boyfriend,
2PM,
X-5,
BEAST,
BIG BANG,
CNBlue,
F.CUZ,
FT-Island,
ZE:A,
Infinite,
MBLAQ,
SS501,
U-Kiss,
TVXQ東方神起,
蘇打綠,
信樂團,
五月天



2012年7月23日 星期一

Nokia Lumia 900 台灣開賣---阿是誰要買啦??!!

"在2012 CES Nokia展出Lumia 900, 並獲選為2012年度CES最佳手機, 這隻搭載Windows Phone 7.5的商務趨向智慧型手機正式在台灣開賣了."


昨天才寫 Titan 空機只要9000元, 現在這支Lumia 一樣的硬體規格, 空機要18900, 加上又是末代的不能升級到 Windows8 的 WindowsPhone 7.5, 真的懷疑, 到底誰要買啊..


雖然我之前也很想買這支啦, 但如果半年前來, 我大概會買, 現在喔, 真要, 買 HTC Titan就好啊.
幾乎一樣的硬體規格
9900對18900,

你會買誰啊??

2012年7月22日 星期日

HTC Titan 只要9900

掉真快, 當初空機買 16900 的, 不過我還滿喜歡這隻手機的, 雖然app 沒有 android 多, 不過使用上還滿好用的.



HTC Titan 泰坦智慧機

‧CPU 1.5GHz處理器
‧4.7吋 WVGA觸控螢幕
‧16GB ROM /512 RAM
‧內建800萬畫素相機
‧HTC Sense& Mango中文版
‧F2.2光圈 28mm 廣角/ BSI
‧5連拍/超簡單全景模式
‧支援Tango 網路視訊電話
‧首款Mango HTC Watch 線上影片服務
‧支援HTC Locations 位置服務
‧支援下載Xbox LIVE game  

網路價 $9900

2012年7月21日 星期六

Android: how to set ListView background, ImageButton background as transparent!!

Sometimes we need a transparent background in Listview and imagebutton,

How to set it in XML?

Here is the answer:

in ImageButton

add this line

android:background="@android:color/transparent"

be noticed that when background of a ImageButton was set to transparent, it will fit the size of it's image.


And in ListView, add this

android:cacheColorHint="#00000000"





2nd app is almost ready.





Asian Pop Male Bands app, is almost ready.
include 17 Korean bands--
Shinee
Super Junior
2AM
2PM
Boyfriend
FT-Island
Big Bang
Beast
X-5
ZE:A
CNBlue
Infinite
F.Cuz
SS501
MBLAQ
U-Kiss
TVXQ
three Taiwanese bands--
五月天
蘇打綠
信樂團


2012年7月18日 星期三

How to decompress an zip file with full folder structure


如何用 java 解壓一個 zip 檔




previously, I write an example about how to zip a folder and keep it original folder structure, 


but how to extract a zip file in java and keep it's original structure?

here is a code snippet--


org.apache.commons.compress.archivers.zip.ZipFile zf = new org.apache.commons.compress.archivers.zip.ZipFile(zipFile);
FileInputStream fis = new FileInputStream(zipFile);
ZipInputStream inputStream = new ZipInputStream(fis);

// Loop through all the files and folders
int exttactCount = 0;
progressDialog.setMax(fileCount);
for (ZipEntry entry = inputStream.getNextEntry(); entry != null; entry = inputStream.getNextEntry()) {
String innerFileName = GlobalConfig.getAlbumFolder() + entry.getName();
File innerFile = new File(innerFileName);
if (innerFile.exists()) {
innerFile.delete();
}

// Check if it is a folder
if (entry.isDirectory()) {
// Its a folder, create that folder
innerFile.mkdirs();
} else {
// Create a file output stream
FileOutputStream outputStream = new FileOutputStream(innerFileName);
final int BUFFER = 2048;

// Buffer the ouput to the file
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream, BUFFER);

// Write the contents
int count = 0;
byte[] data = new byte[BUFFER];
while ((count = inputStream.read(data, 0, BUFFER)) != -1) {
bufferedOutputStream.write(data, 0, count);
}

bufferedOutputStream.flush();
bufferedOutputStream.close();

}

inputStream.closeEntry();

}
inputStream.close();

ps: I really like to use apache common library.

problem in android "Click a button to play sound."

Android Sound Pool example

in android if you want to play a sound when user click a button, the code is like following,

MediaPlayer mp;


Button btn1= (Button) findViewById(R.id.button1);

btn1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
mp= MediaPlayer.create(this, R.raw.sound1);
                                mp.start();
}
});


but there are two issues--


1, when user click the button continually, it will cause an null point exception.
2, the sound delay a bit while when I click the button.

to solve this issue, we need to use another solution --> SoundPool



package com.vimeok.soundpoolexample;

import java.util.HashMap;

import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;


public class SoundManager {

static private SoundManager _instance;
private static SoundPool mSoundPool;
private static HashMap<Integer, Integer> mSoundPoolMap;
private static AudioManager  mAudioManager;
private static Context mContext;

private SoundManager()
{
}

/**
* Requests the instance of the Sound Manager and creates it
* if it does not exist.
*
* @return Returns the single instance of the SoundManager
*/
static synchronized public SoundManager getInstance()
{
   if (_instance == null)
     _instance = new SoundManager();
   return _instance;
}

/**
* Initialises the storage for the sounds
*
* @param theContext The Application context
*/
public static  void initSounds(Context theContext)
{
mContext = theContext;
    mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);
    mSoundPoolMap = new HashMap<Integer, Integer>();
    mAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);  
}

/**
* Add a new Sound to the SoundPool
*
* @param Index - The Sound Index for Retrieval
* @param SoundID - The Android ID for the Sound asset.
*/
public static void addSound(int Index,int SoundID)
{
mSoundPoolMap.put(Index, mSoundPool.load(mContext, SoundID, 1));
}

/**
* Loads the various sound assets
* Currently hardcoded but could easily be changed to be flexible.
*/
public static void loadSounds()
{
mSoundPoolMap.put(1, mSoundPool.load(mContext, R.raw.t0, 1));
mSoundPoolMap.put(2, mSoundPool.load(mContext, R.raw.t1, 1));
mSoundPoolMap.put(3, mSoundPool.load(mContext, R.raw.t2, 1));
mSoundPoolMap.put(4, mSoundPool.load(mContext, R.raw.t3, 1));
mSoundPoolMap.put(5, mSoundPool.load(mContext, R.raw.t4, 1));
mSoundPoolMap.put(6, mSoundPool.load(mContext, R.raw.t5, 1));
mSoundPoolMap.put(7, mSoundPool.load(mContext, R.raw.t6, 1));
mSoundPoolMap.put(8, mSoundPool.load(mContext, R.raw.t7, 1));
mSoundPoolMap.put(9, mSoundPool.load(mContext, R.raw.t8, 1));
mSoundPoolMap.put(10, mSoundPool.load(mContext, R.raw.t9, 1));
mSoundPoolMap.put(11, mSoundPool.load(mContext, R.raw.t11, 1));
mSoundPoolMap.put(12, mSoundPool.load(mContext, R.raw.t12, 1));

}

/**
* Plays a Sound
*
* @param index - The Index of the Sound to be played
* @param speed - The Speed to play not, not currently used but included for compatibility
*/
public static void playSound(int index,float speed)
{
    float streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
    streamVolume = streamVolume / mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
    mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 1, 0, speed);
}

/**
* Stop a Sound
* @param index - index of the sound to be stopped
*/
public static void stopSound(int index)
{
mSoundPool.stop(mSoundPoolMap.get(index));
}

public static void cleanup()
{
mSoundPool.release();
mSoundPool = null;
   mSoundPoolMap.clear();
   mAudioManager.unloadSoundEffects();
   _instance = null;
 
}
}

then in your main activity,
...
...
...

SoundManager.getInstance();
SoundManager.initSounds(this);
SoundManager.loadSounds();


btn1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
                                //playsound
SoundManager.playSound(1, 1);
}
});
...
...
...





Leica X2



Leica 在柏林的發表會中做了幾乎是全產品線的更新,除了奇特概念的黑白相機 M Monochrome 外,X1 的後繼機種 X2 也同時發表。X2 外型上與 X1 並無太大的變化,鏡頭也是使用相同的 Elmarit 24mm f/2.8 ASPH 。X2 使用了 16.5MP APS-C CMOS 感光元件(X1 為 12.2MP)、2.7" 23 萬像素 LCD 螢幕。換算等效焦距約為 35mm,對於抓拍以及 Street snap 都是非常適合的,官方也表示 X2 的對焦系統比起 X1 會更為靈敏與準確。
而此次 X2 另一亮點就是配件的多元化,除了機頂熱靴可外接 Leica SF 24D 和 SF 58 閃光燈外。還有外接電子取景器來因應光線太強所造成的 LCD 取景困難,由圖片也可以看到 X2 另外有前握把與光學取景器的配件。配合 X2 其直覺式的操作下對於拍攝上可以更快速適應並得心應手,但可惜的是與 X1 相同依然沒有錄影功能。

Leica X2 規格簡介
  • 16.5MP APS-C CMOS 感光元件(有效像素 16.2MP)
  • 2.7" 23 萬像素 LCD 螢幕
  • 鏡頭為 Elmarit 24mm f/2.8 ASPH(等效焦距約 35mm)
  • ISO 感光值 ISO100-ISO12500、連拍速度每秒 3 or 5fps
  • 支援 RAW 檔拍攝、HDMI輸出
  • 無錄製影片功能
  • 尺寸大小:124 x 69 x 52 mm、重量 450g
  • 儲存格式:SD/SDHC

2012年7月17日 星期二

How to get Youtube MP4 video using java?



import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;

public class Parser {

private static String vid="c2ovrKzRezw";
private static String url="http://www.youtube.com/get_video_info?video_id="+vid;//xzWJvDTfWyc";

static String pattern3="video/mp4";
public static void main(String args[]){
try {
String result= getMessageFromUrl(url);
//System.err.println(result);
String p_result=java.net.URLDecoder.decode(java.net.URLDecoder.decode(result, "UTF-8"),"UTF-8");
//結果太長了, 沒研究是否可以用正規表示式處理, 先用暴力方法解決
  // if somebody know how to use reg press to parse the result, please let me know.
// currently, I just hard code to parse mp4 url
int last=p_result.lastIndexOf("type=video/mp4");
String s2= p_result.substring(0,last+15);
int lasthttp= s2.lastIndexOf("http://");
String mp4Url=s2.substring(lasthttp, s2.length()-1);
System.err.println(mp4Url);
//ok, now save it to disk
File f= new File("d:\\"+vid+".mp4");
org.apache.commons.io.FileUtils.copyURLToFile(new URL(mp4Url),f);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public static String getMessageFromUrl(String msgUrl) throws IOException {
URL url = new URL(msgUrl);
BufferedReader in = new BufferedReader(new InputStreamReader(
url.openStream()));
String inputLine;
StringBuffer sb = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
sb.append(inputLine);
}
in.close();
return sb.toString();
}

}

that means you can also save youtube video in your android app.
but 18+ video can't be download, it may need to integrate with youtube api to download 18+ video.



蒜泥白肉


蒜泥白肉
食材:
三層肉一塊(150克)、蒜頭10顆、小黃瓜1條、銀芽50克
調味料:
醬油膏、烏醋、味醂
做法:
1.五花肉去皮,肉塊對剖切半,滾水鍋中加入米酒,放入五花肉塊以小火燜煮泡熟。
2.調醬汁:醬油膏50克+水25克+味醂25克+蒜頭10顆,入調理機中打泥過濾,再加少許醬油、紅油、烏醋和香油調味。
3.將濾出的蒜渣放入水鍋中一起燜煮。
4.小黃瓜切絲泡冷水;銀芽汆燙泡冷水,瀝乾水分鋪於盤底。
5.煮好的五花肉拉大薄片排盤,將醬汁澆淋於上即可。
ps. 帶皮的無花不錯, 不用去皮, 燙好後, 放到冰塊堆裡滾一下, 皮就超Q

Why I have to create an adsense account?

I do not know why I need an Adsense account to get pay, if I want to sell app in android market.

I create this adsense account just use to sell app, so, if you google adsense team read this post, please don't not reject due to not so much contents in this blog.

少女時代&韓國少女團體 MV app

今天上線的第一個app









在WindowPhone 7 中, 開啟 Youtube 影片最簡單的方法.

當然你也可以用 WebBrowserTask  來開.
private void openYouTube(String vid)
 {

            WebBrowserTask task = new WebBrowserTask();
            String uri = "http://www.youtube.com/embed/" + vid + "?autoplay=1&hd=1";
            task.Uri = new Uri(uri);
            task.Show();
}

但用 webview user 就知道是youtube 的影片, 感覺不好..

最好的方法是可以用WindowPhone 的 MediaPlayer 來開啟影片,
要達到這樣的功能對剛開始寫 WindowPhone, C# 的我來說, 有點困難, 後來找到一個好東西

MyToolKit
"MyToolkit is a collection of useful classes for WinRT, Windows Phone, Silverlight and WPF. These classes have been developed or collected by Rico Suter. "
網址在這邊..
http://mytoolkit.codeplex.com/

只要這樣
MyToolkit.Multimedia.YouTube.Play(videoId, YouTubeQuality.Quality480P, null);

就可以用 MediaPlayer 放影片了, 不過18+的影片需要認證, 可能要透過整合 Google API 才能撥, 一般的影片都沒問題.
連在 andoird 用 mediaplayer 因有版權問題不能放的影片, 在 WindowsPhone 7 的 MediaPlayer 一樣可以放, 強....

其實我還滿喜歡 WindowPhone 的, 不過用的人少, 好用的 app 也不多.

以下畫面是我的 WindowPhone App, "MusicTube++"
http://www.windowsphone.com/zh-TW/apps/4ce8e82b-5000-4af1-870b-7e06e1bd4fd8




Save URL jpg to file using Objective C in GNUStep

#import <Foundation/Foundation.h>
#import <Foundation/NSUrl.h>

int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog (@"hello world");
NSURL *url = [NSURL URLWithString:@"url contains myconetnt"];
NSError *theNetworkError;
    NSString *content = [NSString stringWithContentsOfURL:url encoding:NSASCIIStringEncoding error:&theNetworkError];
    NSInteger len= [content length];
    //NSLog(@"%@, contains %i characters",content, len);
    NSString *content2= [content substringToIndex:(len-3)];
    NSString *content3=[content2 stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSLog(@"%@",content3);
    NSString *myImage = @"http://www.iphonedevsdk.com/forum/images/appads/blueprint.jpg";
NSString *tempImagemUrl = [myImage stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSURL *url1 = [NSURL URLWithString:tempImagemUrl];
NSData *mydata = [NSData dataWithContentsOfURL:url1];
NSString *fileName=@"test.jpg";
    BOOL b=[mydata writeToFile:fileName atomically:true];
[pool drain];
return 0;
}